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 38 Renderer * Renderer::instance() 39 { 40 if (m_instance == NULL) m_instance = new Renderer; 41 return m_instance; 42 } 43 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 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 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 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 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 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 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