Home | History | Annotate | Download | only in ut_renderer
      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