• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <assert.h>
20 #include "RenderingThread.h"
21 #include "Renderer.h"
22 
23 // include operating-system dependent windowing system impelemntation
24 #ifdef _WIN32
25 #    error "WINDOWS IS NOT SUPPORTED AT THE MOMENT"
26 #elif defined __APPLE__
27 #    error "Apple OS-X IS NOT SUPPORTED"
28 #elif defined (__unix__)
29 # include "X11Windowing.h"
30 #endif
31 
32 
33 
34 
35 
36 Renderer * Renderer::m_instance = NULL;
37 
instance()38 Renderer * Renderer::instance()
39 {
40     if (m_instance == NULL) m_instance = new Renderer;
41     return m_instance;
42 }
43 
Renderer()44 Renderer::Renderer()
45 {
46     // Unix specific, use your platform specific windowing implementation
47 #ifdef __unix__
48     m_nw = new X11Windowing;
49 #endif
50 
51     m_dpy = eglGetDisplay(m_nw->getNativeDisplay());
52     EGLint major, minor;
53     eglInitialize(m_dpy, &major, &minor);
54     fprintf(stderr, "egl initialized : %d.%d\n", major, minor);
55 }
56 
createSurface(RenderingThread * thread,const ClientHandle & handle)57 int Renderer::createSurface(RenderingThread *thread, const ClientHandle & handle)
58 {
59     android::Mutex::Autolock(this->m_mutex);
60 
61     assert(m_surfaces.find(handle) == m_surfaces.end());
62     if (handle.handle == 0) {
63         fprintf(stderr, "trying to create surface for EGL_NO_SURFACE !!!\n");
64         return -1;
65     } else {
66         RendererSurface  *surface = RendererSurface::create(m_dpy, RendererSurface::CONFIG_DEPTH, m_nw);
67         if (surface == NULL) {
68             printf("failed to create surface !!\n");
69             return -1;
70         }
71         m_surfaces.insert(SurfaceMap::value_type(handle, surface));
72     }
73     return 0;
74 }
75 
destroySurface(RenderingThread * thread,const ClientHandle & handle)76 int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle)
77 {
78     android::Mutex::Autolock(this->m_mutex);
79 
80     SurfaceMap::iterator i = m_surfaces.find(handle);
81     if (i == m_surfaces.end()) {
82         printf("removing surface that doesn't exists\n");
83         return -1;
84     }
85     if (i->second->destroy(m_nw)) {
86         m_surfaces.erase(handle);
87     }
88     return 0;
89 }
90 
createContext(RenderingThread * thread,const ClientHandle & handle,ClientHandle shareCtx,int version)91 int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx, int version)
92 {
93     android::Mutex::Autolock(this->m_mutex);
94 
95     assert(m_ctxs.find(handle) == m_ctxs.end());
96     RendererContext *shared = NULL;
97     if (shareCtx.handle != 0) {
98         ContextMap::iterator sctx = m_ctxs.find(shareCtx);
99         if (sctx != m_ctxs.end()) {
100             shared = sctx->second;
101         }
102     }
103 
104     RendererContext *ctx =
105         RendererContext::create(m_dpy,
106                                 RendererSurface::getEglConfig(m_dpy, RendererSurface::CONFIG_DEPTH),
107                                 shared, version);
108     if (ctx == NULL) {
109         fprintf(stderr, "failed to create context\n");
110         return -1;
111     }
112     m_ctxs.insert(ContextMap::value_type(handle, ctx));
113     return 0;
114 }
115 
destroyContext(RenderingThread * thread,const ClientHandle & handle)116 int Renderer::destroyContext(RenderingThread *thread, const ClientHandle &handle)
117 {
118     android::Mutex::Autolock(this->m_mutex);
119 
120     ContextMap::iterator i = m_ctxs.find(handle);
121     if (i == m_ctxs.end()) {
122         printf("removing context that doesn't exists\n");
123         return -1;
124     }
125     if (i->second->destroy()) {
126         m_ctxs.erase(handle);
127     }
128     return 0;
129 }
130 
makeCurrent(RenderingThread * thread,const ClientHandle & drawSurface,const ClientHandle & readSurface,const ClientHandle & ctx)131 int Renderer::makeCurrent(RenderingThread *thread,
132                           const ClientHandle &drawSurface,
133                           const ClientHandle &readSurface,
134                           const ClientHandle & ctx)
135 {
136     android::Mutex::Autolock(this->m_mutex);
137 
138     RendererContext *currentContext = thread->currentContext();
139 
140     ContextMap::iterator c = m_ctxs.find(ctx);
141     EGLContext eglContext;
142     if (ctx.handle != 0 && c != m_ctxs.end()) {
143         if (c->second != currentContext) {
144             // new context is set
145             if (currentContext != NULL) currentContext->unref();
146             c->second->ref();
147             eglContext = c->second->eglContext();
148             thread->setCurrentContext(c->second);
149             thread->glDecoder().setContextData(&c->second->decoderContextData());
150             thread->gl2Decoder().setContextData(&c->second->decoderContextData());
151         } else {
152             // same context is already set
153             eglContext = c->second->eglContext();
154         }
155     } else {
156         eglContext = EGL_NO_CONTEXT;
157         if (currentContext != NULL) currentContext->unref();
158         thread->setCurrentContext(NULL);
159         thread->glDecoder().setContextData(NULL);
160         thread->gl2Decoder().setContextData(NULL);
161     }
162 
163     EGLSurface draw = EGL_NO_SURFACE;
164     EGLSurface read = EGL_NO_SURFACE;
165     SurfaceMap::iterator i;
166     i = m_surfaces.find(drawSurface);   if (i != m_surfaces.end()) draw = i->second->eglSurface();
167     i = m_surfaces.find(readSurface);   if (i != m_surfaces.end()) read = i->second->eglSurface();
168 
169     return eglMakeCurrent(m_dpy, draw, read, eglContext);
170 }
171 
swapBuffers(RenderingThread * thread,const ClientHandle & surface)172 int Renderer::swapBuffers(RenderingThread *thread,
173                           const ClientHandle &surface)
174 {
175     android::Mutex::Autolock(this->m_mutex);
176 
177     SurfaceMap::iterator s = m_surfaces.find(surface);
178     if (s == m_surfaces.end()) {
179         fprintf(stderr, "swapping buffers for non existing surface\n");
180         return -1;
181     }
182     return eglSwapBuffers(m_dpy, s->second->eglSurface());
183 }
184