Home | History | Annotate | Download | only in mesa
      1 #include "SkEGLContext.h"
      2 #include "SkTypes.h"
      3 
      4 #include "GL/osmesa.h"
      5 #include "GL/glu.h"
      6 
      7 #define SK_GL_DECL_PROC(T, F) T F ## _func = NULL;
      8 #define SK_GL_GET_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F);
      9 #define SK_GL_GET_EXT_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F "EXT");
     10 
     11 SkEGLContext::SkEGLContext() : context(NULL), image(NULL) {
     12 }
     13 
     14 SkEGLContext::~SkEGLContext() {
     15     if (this->image)
     16         free(this->image);
     17 
     18     if (this->context)
     19         OSMesaDestroyContext(this->context);
     20 }
     21 
     22 #if SK_B32_SHIFT < SK_G32_SHIFT &&\
     23                    SK_G32_SHIFT < SK_R32_SHIFT &&\
     24                                   SK_R32_SHIFT < SK_A32_SHIFT
     25     #define SK_OSMESA_COLOR_ORDER OSMESA_BGRA
     26 #elif SK_R32_SHIFT < SK_G32_SHIFT &&\
     27                      SK_G32_SHIFT < SK_B32_SHIFT &&\
     28                                     SK_B32_SHIFT < SK_A32_SHIFT
     29     #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
     30 #elif SK_A32_SHIFT < SK_R32_SHIFT && \
     31                      SK_R32_SHIFT < SK_G32_SHIFT && \
     32                                     SK_G32_SHIFT < SK_B32_SHIFT
     33     #define SK_OSMESA_COLOR_ORDER OSMESA_ARGB
     34 #else
     35     //Color order (rgba) SK_R32_SHIFT SK_G32_SHIFT SK_B32_SHIFT SK_A32_SHIFT
     36     #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
     37 #endif
     38 
     39 bool SkEGLContext::init(const int width, const int height) {
     40     /* Create an RGBA-mode context */
     41 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
     42     /* specify Z, stencil, accum sizes */
     43     OSMesaContext ctx = OSMesaCreateContextExt(SK_OSMESA_COLOR_ORDER, 16, 0, 0, NULL);
     44 #else
     45     OSMesaContext ctx = OSMesaCreateContext(SK_OSMESA_COLOR_ORDER, NULL);
     46 #endif
     47     if (!ctx) {
     48         SkDebugf("OSMesaCreateContext failed!\n");
     49         return false;
     50     }
     51     this->context = ctx;
     52 
     53     // Allocate the image buffer
     54     GLfloat *buffer = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
     55     if (!buffer) {
     56         SkDebugf("Alloc image buffer failed!\n");
     57         return false;
     58     }
     59     this->image = buffer;
     60 
     61     // Bind the buffer to the context and make it current
     62     if (!OSMesaMakeCurrent(ctx, buffer, GL_FLOAT, width, height)) {
     63         SkDebugf("OSMesaMakeCurrent failed!\n");
     64         return false;
     65     }
     66 
     67     //Setup the framebuffers
     68     SK_GL_DECL_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
     69     SK_GL_DECL_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
     70     SK_GL_DECL_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
     71     SK_GL_DECL_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
     72     SK_GL_DECL_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
     73     SK_GL_DECL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
     74     SK_GL_DECL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
     75 
     76     const GLubyte* glExts = glGetString(GL_EXTENSIONS);
     77     if (gluCheckExtension(
     78           reinterpret_cast<const GLubyte*>("GL_ARB_framebuffer_object")
     79           , glExts))
     80     {
     81         SK_GL_GET_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
     82         SK_GL_GET_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
     83         SK_GL_GET_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
     84         SK_GL_GET_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
     85         SK_GL_GET_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
     86         SK_GL_GET_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
     87         SK_GL_GET_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
     88 
     89     //osmesa on mac currently only supports EXT
     90     } else if (gluCheckExtension(
     91           reinterpret_cast<const GLubyte*>("GL_EXT_framebuffer_object")
     92           , glExts))
     93     {
     94         SK_GL_GET_EXT_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
     95         SK_GL_GET_EXT_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
     96         SK_GL_GET_EXT_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
     97         SK_GL_GET_EXT_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
     98         SK_GL_GET_EXT_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
     99         SK_GL_GET_EXT_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
    100         SK_GL_GET_EXT_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
    101     } else {
    102       SkDebugf("GL_ARB_framebuffer_object not found.\n");
    103       return false;
    104     }
    105 
    106     GLuint fboID;
    107     GLuint cbID;
    108     GLuint dsID;
    109     glGenFramebuffers_func(1, &fboID);
    110     glBindFramebuffer_func(GL_FRAMEBUFFER, fboID);
    111 
    112     glGenRenderbuffers_func(1, &cbID);
    113     glBindRenderbuffer_func(GL_RENDERBUFFER, cbID);
    114     glRenderbufferStorage_func(GL_RENDERBUFFER, OSMESA_RGBA, width, height);
    115     glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cbID);
    116 
    117     glGenRenderbuffers_func(1, &dsID);
    118     glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, dsID);
    119     glRenderbufferStorage_func(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
    120     glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dsID);
    121 
    122     glViewport(0, 0, width, height);
    123     glClearStencil(0);
    124     glClear(GL_STENCIL_BUFFER_BIT);
    125 
    126     GLenum status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER);
    127     return GL_FRAMEBUFFER_COMPLETE == status;
    128 }
    129