Home | History | Annotate | Download | only in android
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "gl/SkNativeGLContext.h"
      9 
     10 SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
     11     fOldEGLContext = eglGetCurrentContext();
     12     fOldDisplay = eglGetCurrentDisplay();
     13     fOldSurface = eglGetCurrentSurface(EGL_DRAW);
     14 
     15 }
     16 
     17 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
     18     if (NULL != fOldDisplay) {
     19         eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext);
     20     }
     21 }
     22 
     23 ///////////////////////////////////////////////////////////////////////////////
     24 
     25 SkNativeGLContext::SkNativeGLContext()
     26     : fContext(EGL_NO_CONTEXT)
     27     , fDisplay(EGL_NO_DISPLAY)
     28     , fSurface(EGL_NO_SURFACE) {
     29 }
     30 
     31 SkNativeGLContext::~SkNativeGLContext() {
     32     this->destroyGLContext();
     33 }
     34 
     35 void SkNativeGLContext::destroyGLContext() {
     36     if (fDisplay) {
     37         eglMakeCurrent(fDisplay, 0, 0, 0);
     38 
     39         if (fContext) {
     40             eglDestroyContext(fDisplay, fContext);
     41             fContext = EGL_NO_CONTEXT;
     42         }
     43 
     44         if (fSurface) {
     45             eglDestroySurface(fDisplay, fSurface);
     46             fSurface = EGL_NO_SURFACE;
     47         }
     48 
     49         //TODO should we close the display?
     50         fDisplay = EGL_NO_DISPLAY;
     51     }
     52 }
     53 
     54 const GrGLInterface* SkNativeGLContext::createGLContext() {
     55     static const EGLint kEGLContextAttribsForOpenGL[] = {
     56         EGL_NONE
     57     };
     58 
     59     static const EGLint kEGLContextAttribsForOpenGLES[] = {
     60         EGL_CONTEXT_CLIENT_VERSION, 2,
     61         EGL_NONE
     62     };
     63 
     64     static const struct {
     65         const EGLint* fContextAttribs;
     66         EGLenum fAPI;
     67         EGLint  fRenderableTypeBit;
     68         GrGLStandard fStandard;
     69     } kAPIs[] = {
     70         {   // OpenGL
     71             kEGLContextAttribsForOpenGL,
     72             EGL_OPENGL_API,
     73             EGL_OPENGL_BIT,
     74             kGL_GrGLStandard
     75         },
     76         {   // OpenGL ES. This seems to work for both ES2 and 3 (when available).
     77             kEGLContextAttribsForOpenGLES,
     78             EGL_OPENGL_ES_API,
     79             EGL_OPENGL_ES2_BIT,
     80             kGLES_GrGLStandard
     81         },
     82     };
     83 
     84     const GrGLInterface* interface = NULL;
     85 
     86     for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) {
     87         fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     88 
     89         EGLint majorVersion;
     90         EGLint minorVersion;
     91         eglInitialize(fDisplay, &majorVersion, &minorVersion);
     92 
     93 #if 0
     94         SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
     95         SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
     96         SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION));
     97         SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
     98 #endif
     99 
    100         if (!eglBindAPI(kAPIs[api].fAPI)) {
    101             continue;
    102         }
    103 
    104         EGLint numConfigs;
    105         const EGLint configAttribs[] = {
    106             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    107             EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit,
    108             EGL_RED_SIZE, 8,
    109             EGL_GREEN_SIZE, 8,
    110             EGL_BLUE_SIZE, 8,
    111             EGL_ALPHA_SIZE, 8,
    112             EGL_NONE
    113         };
    114 
    115         EGLConfig surfaceConfig;
    116         if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
    117             SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError());
    118             continue;
    119         }
    120 
    121         fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs);
    122         if (EGL_NO_CONTEXT == fContext) {
    123             SkDebugf("eglCreateContext failed.  EGL Error: 0x%08x\n", eglGetError());
    124             continue;
    125         }
    126 
    127         static const EGLint kSurfaceAttribs[] = {
    128             EGL_WIDTH, 1,
    129             EGL_HEIGHT, 1,
    130             EGL_NONE
    131         };
    132 
    133         fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs);
    134         if (EGL_NO_SURFACE == fSurface) {
    135             SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError());
    136             this->destroyGLContext();
    137             continue;
    138         }
    139 
    140         if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
    141             SkDebugf("eglMakeCurrent failed.  EGL Error: 0x%08x\n", eglGetError());
    142             this->destroyGLContext();
    143             continue;
    144         }
    145 
    146         interface = GrGLCreateNativeInterface();
    147         if (NULL == interface) {
    148             SkDebugf("Failed to create gl interface.\n");
    149             this->destroyGLContext();
    150             continue;
    151         }
    152 
    153         if (!interface->validate()) {
    154             interface->unref();
    155             interface = NULL;
    156             this->destroyGLContext();
    157         }
    158     }
    159 
    160     return interface;
    161 }
    162 
    163 void SkNativeGLContext::makeCurrent() const {
    164     if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
    165         SkDebugf("Could not set the context.\n");
    166     }
    167 }
    168 
    169 void SkNativeGLContext::swapBuffers() const {
    170     if (!eglSwapBuffers(fDisplay, fSurface)) {
    171         SkDebugf("Could not complete eglSwapBuffers.\n");
    172     }
    173 }
    174