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