aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-19 17:47:02 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-19 17:47:02 +0000
commit0e45441994a36a78a7a14681799ac519a2b8aae7 (patch)
tree9bcce5f1cb1e448525054ec9af693c019c500f09
parent65245ade841a7aa4d71b1760c081959c71cb4560 (diff)
Add Mesa as a GL backend.
-rw-r--r--Makefile51
-rw-r--r--gpu/src/mesa/GrGLDefaultInterface_mesa.cpp183
-rw-r--r--include/utils/SkEGLContext.h11
-rw-r--r--src/utils/mesa/SkEGLContext_Mesa.cpp128
4 files changed, 359 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 32a793ff03..0bf35749df 100644
--- a/Makefile
+++ b/Makefile
@@ -96,27 +96,48 @@ ifeq ($(SKIA_BUILD_FOR),mac)
# CC := gcc-4.0 $(SDK_OPTS)
C_INCLUDES += -I/opt/local/include
- LINKER_OPTS += -L/opt/local/lib -framework Carbon -lpng -framework OpenGL -framework AGL
+ LINKER_OPTS += -L/opt/local/lib -framework Carbon -lpng
DEFINES += -DSK_BUILD_FOR_MAC -DSK_ENABLE_LIBPNG
-
+ ifeq ($(SKIA_MESA),true)
+ C_INCLUDES += -I/usr/X11/include
+ LINKER_OPTS += -L/usr/X11/lib -lOSMesa -lGLU
+ DEFINES += -DSK_MESA
+ else
+ LINKER_OPTS += -framework OpenGL -framework AGL
+ endif
C_INCLUDES += -Iinclude/utils/mac
# SRC_LIST += src/ports/SkImageDecoder_CG.cpp
SRC_LIST += src/utils/mac/SkCreateCGImageRef.cpp
- SRC_LIST += src/utils/mac/SkEGLContext_mac.cpp
+ ifeq ($(SKIA_MESA),true)
+ SRC_LIST += src/utils/mesa/SkEGLContext_Mesa.cpp
+ else
+ SRC_LIST += src/utils/mac/SkEGLContext_mac.cpp
+ endif
SRC_LIST += src/core/SkTypefaceCache.cpp
SRC_LIST += src/ports/SkFontHost_mac_coretext.cpp
- # these are our registry-based factories
+ # these are our registry-based factories
SRC_LIST += src/images/SkImageDecoder_Factory.cpp
SRC_LIST += src/images/SkImageEncoder_Factory.cpp
SRC_LIST += src/images/SkImageDecoder_libpng.cpp
- # support files
+ # support files
SRC_LIST += src/images/SkScaledBitmapSampler.cpp
- SRC_LIST += gpu/src/mac/GrGLDefaultInterface_mac.cpp
+ ifeq ($(SKIA_MESA),true)
+ SRC_LIST += gpu/src/mesa/GrGLDefaultInterface_mesa.cpp
+ else
+ SRC_LIST += gpu/src/mac/GrGLDefaultInterface_mac.cpp
+ endif
+
else
- LINKER_OPTS += -lpng -lfreetype -lGL -lGLU -lX11
+ LINKER_OPTS += -lpng -lfreetype
DEFINES += -DSK_BUILD_FOR_UNIX -DSK_ENABLE_LIBPNG -DGR_LINUX_BUILD=1
+ ifeq ($(SKIA_MESA),true)
+ LINKER_OPTS += -lOSMesa -lGLU
+ DEFINES += -DSK_MESA
+ else
+ LINKER_OPTS += -lGL -lGLU -lX11
+ endif
#Assume the color order for now.
DEFINES += -DSK_SAMPLES_FOR_X
@@ -127,15 +148,23 @@ else
SRC_LIST += src/ports/SkFontHost_gamma_none.cpp
SRC_LIST += src/ports/SkFontHost_FreeType.cpp
SRC_LIST += src/ports/SkFontHost_FreeType_Subpixel.cpp
- SRC_LIST += src/utils/unix/SkEGLContext_Unix.cpp
- # these are our registry-based factories
+ ifeq ($(SKIA_MESA),true)
+ SRC_LIST += src/utils/mesa/SkEGLContext_Mesa.cpp
+ else
+ SRC_LIST += src/utils/unix/SkEGLContext_Unix.cpp
+ endif
+ # these are our registry-based factories
SRC_LIST += src/images/SkImageDecoder_Factory.cpp
SRC_LIST += src/images/SkImageEncoder_Factory.cpp
SRC_LIST += src/images/SkImageDecoder_libpng.cpp
- # support files
+ # support files
SRC_LIST += src/images/SkScaledBitmapSampler.cpp
- SRC_LIST += gpu/src/unix/GrGLDefaultInterface_unix.cpp
+ ifeq ($(SKIA_MESA),true)
+ SRC_LIST += gpu/src/mesa/GrGLDefaultInterface_mesa.cpp
+ else
+ SRC_LIST += gpu/src/unix/GrGLDefaultInterface_unix.cpp
+ endif
endif
# For these files, and these files only, compile with -msse2.
diff --git a/gpu/src/mesa/GrGLDefaultInterface_mesa.cpp b/gpu/src/mesa/GrGLDefaultInterface_mesa.cpp
new file mode 100644
index 0000000000..b494d76baa
--- /dev/null
+++ b/gpu/src/mesa/GrGLDefaultInterface_mesa.cpp
@@ -0,0 +1,183 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "GrGLInterface.h"
+
+#include "GL/osmesa.h"
+#include <GL/glext.h>
+#include <GL/glu.h>
+
+#define GR_GL_GET_PROC(F) gDefaultInterface.f ## F = (GrGL ## F ## Proc) \
+ OSMesaGetProcAddress("gl" #F);
+#define GR_GL_GET_PROC_SUFFIX(F, S) gDefaultInterface.f ## F = (GrGL ## F ## Proc) \
+ OSMesaGetProcAddress("gl" #F #S);
+
+void GrGLSetDefaultGLInterface() {
+ static GrGLInterface gDefaultInterface;
+ static bool gDefaultInterfaceInit;
+ if (!gDefaultInterfaceInit && NULL != OSMesaGetCurrentContext()) {
+ int major, minor;
+ const char* versionString = (const char*) glGetString(GL_VERSION);
+ const char* extString = (const char*) glGetString(GL_EXTENSIONS);
+ gl_version_from_string(&major, &minor, versionString);
+
+ if (major == 1 && minor < 5) {
+ // We must have array and element_array buffer objects.
+ return;
+ }
+
+ gDefaultInterface.fActiveTexture = glActiveTexture;
+ GR_GL_GET_PROC(AttachShader);
+ GR_GL_GET_PROC(BindAttribLocation);
+ GR_GL_GET_PROC(BindBuffer);
+ gDefaultInterface.fBindTexture = glBindTexture;
+ gDefaultInterface.fBlendColor = glBlendColor;
+ gDefaultInterface.fBlendFunc = glBlendFunc;
+ GR_GL_GET_PROC(BufferData);
+ GR_GL_GET_PROC(BufferSubData);
+ gDefaultInterface.fClear = glClear;
+ gDefaultInterface.fClearColor = glClearColor;
+ gDefaultInterface.fClearStencil = glClearStencil;
+ gDefaultInterface.fClientActiveTexture = glClientActiveTexture;
+ gDefaultInterface.fColorMask = glColorMask;
+ gDefaultInterface.fColorPointer = glColorPointer;
+ gDefaultInterface.fColor4ub = glColor4ub;
+ GR_GL_GET_PROC(CompileShader);
+ gDefaultInterface.fCompressedTexImage2D = glCompressedTexImage2D;
+ GR_GL_GET_PROC(CreateProgram);
+ GR_GL_GET_PROC(CreateShader);
+ gDefaultInterface.fCullFace = glCullFace;
+ GR_GL_GET_PROC(DeleteBuffers);
+ GR_GL_GET_PROC(DeleteProgram);
+ GR_GL_GET_PROC(DeleteShader);
+ gDefaultInterface.fDeleteTextures = glDeleteTextures;
+ gDefaultInterface.fDepthMask = glDepthMask;
+ gDefaultInterface.fDisable = glDisable;
+ gDefaultInterface.fDisableClientState = glDisableClientState;
+ GR_GL_GET_PROC(DisableVertexAttribArray);
+ gDefaultInterface.fDrawArrays = glDrawArrays;
+ gDefaultInterface.fDrawElements = glDrawElements;
+ gDefaultInterface.fEnable = glEnable;
+ gDefaultInterface.fEnableClientState = glEnableClientState;
+ GR_GL_GET_PROC(EnableVertexAttribArray);
+ gDefaultInterface.fFrontFace = glFrontFace;
+ GR_GL_GET_PROC(GenBuffers);
+ GR_GL_GET_PROC(GetBufferParameteriv);
+ gDefaultInterface.fGetError = glGetError;
+ gDefaultInterface.fGetIntegerv = glGetIntegerv;
+ GR_GL_GET_PROC(GetProgramInfoLog);
+ GR_GL_GET_PROC(GetProgramiv);
+ GR_GL_GET_PROC(GetShaderInfoLog);
+ GR_GL_GET_PROC(GetShaderiv);
+ gDefaultInterface.fGetString = glGetString;
+ gDefaultInterface.fGenTextures = glGenTextures;
+ GR_GL_GET_PROC(GetUniformLocation);
+ gDefaultInterface.fLineWidth = glLineWidth;
+ GR_GL_GET_PROC(LinkProgram);
+ gDefaultInterface.fLoadMatrixf = glLoadMatrixf;
+ GR_GL_GET_PROC(MapBuffer);
+ gDefaultInterface.fMatrixMode = glMatrixMode;
+ gDefaultInterface.fPointSize = glPointSize;
+ gDefaultInterface.fPixelStorei = glPixelStorei;
+ gDefaultInterface.fReadPixels = glReadPixels;
+ gDefaultInterface.fScissor = glScissor;
+ gDefaultInterface.fShadeModel = glShadeModel;
+ GR_GL_GET_PROC(ShaderSource);
+ gDefaultInterface.fStencilFunc = glStencilFunc;
+ GR_GL_GET_PROC(StencilFuncSeparate);
+ gDefaultInterface.fStencilMask = glStencilMask;
+ GR_GL_GET_PROC(StencilMaskSeparate);
+ gDefaultInterface.fStencilOp = glStencilOp;
+ GR_GL_GET_PROC(StencilOpSeparate);
+ gDefaultInterface.fTexCoordPointer = glTexCoordPointer;
+ gDefaultInterface.fTexEnvi = glTexEnvi;
+ //OSMesa on Mac's glTexImage2D takes a GLenum for internalFormat rather than a GLint.
+ gDefaultInterface.fTexImage2D = reinterpret_cast<GrGLTexImage2DProc>(glTexImage2D);
+ gDefaultInterface.fTexParameteri = glTexParameteri;
+ gDefaultInterface.fTexSubImage2D = glTexSubImage2D;
+ GR_GL_GET_PROC(Uniform1f);
+ GR_GL_GET_PROC(Uniform1i);
+ GR_GL_GET_PROC(Uniform1fv);
+ GR_GL_GET_PROC(Uniform1iv);
+ GR_GL_GET_PROC(Uniform2f);
+ GR_GL_GET_PROC(Uniform2i);
+ GR_GL_GET_PROC(Uniform2fv);
+ GR_GL_GET_PROC(Uniform2iv);
+ GR_GL_GET_PROC(Uniform3f);
+ GR_GL_GET_PROC(Uniform3i);
+ GR_GL_GET_PROC(Uniform3fv);
+ GR_GL_GET_PROC(Uniform3iv);
+ GR_GL_GET_PROC(Uniform4f);
+ GR_GL_GET_PROC(Uniform4i);
+ GR_GL_GET_PROC(Uniform4fv);
+ GR_GL_GET_PROC(Uniform4iv);
+ GR_GL_GET_PROC(UniformMatrix2fv);
+ GR_GL_GET_PROC(UniformMatrix3fv);
+ GR_GL_GET_PROC(UniformMatrix4fv);
+ GR_GL_GET_PROC(UnmapBuffer);
+ GR_GL_GET_PROC(UseProgram);
+ GR_GL_GET_PROC(VertexAttrib4fv);
+ GR_GL_GET_PROC(VertexAttribPointer);
+ gDefaultInterface.fVertexPointer = glVertexPointer;
+ gDefaultInterface.fViewport = glViewport;
+
+ // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
+ // GL_ARB_framebuffer_object doesn't use ARB suffix.)
+ if (major >= 3 || has_gl_extension_from_string(
+ "GL_ARB_framebuffer_object", extString)) {
+ GR_GL_GET_PROC(GenFramebuffers);
+ GR_GL_GET_PROC(BindFramebuffer);
+ GR_GL_GET_PROC(FramebufferTexture2D);
+ GR_GL_GET_PROC(CheckFramebufferStatus);
+ GR_GL_GET_PROC(DeleteFramebuffers);
+ GR_GL_GET_PROC(RenderbufferStorage);
+ GR_GL_GET_PROC(GenRenderbuffers);
+ GR_GL_GET_PROC(DeleteRenderbuffers);
+ GR_GL_GET_PROC(FramebufferRenderbuffer);
+ GR_GL_GET_PROC(BindRenderbuffer);
+ GR_GL_GET_PROC(RenderbufferStorageMultisample);
+ GR_GL_GET_PROC(BlitFramebuffer);
+ } else if (has_gl_extension_from_string("GL_EXT_framebuffer_object",
+ extString)) {
+ GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
+ GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
+ GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
+ GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
+ GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
+ GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
+ GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
+ GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
+ GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
+ GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
+ if (has_gl_extension_from_string("GL_EXT_framebuffer_multisample",
+ extString)) {
+ GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
+ }
+ if (has_gl_extension_from_string("GL_EXT_framebuffer_blit",
+ extString)) {
+ GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
+ }
+ } else {
+ // we must have FBOs
+ return;
+ }
+ gDefaultInterface.fBindingsExported = kDesktop_GrGLBinding;
+
+ gDefaultInterfaceInit = true;
+ }
+ if (gDefaultInterfaceInit)
+ GrGLSetGLInterface(&gDefaultInterface);
+}
diff --git a/include/utils/SkEGLContext.h b/include/utils/SkEGLContext.h
index 6aa8518e53..d67cf0c317 100644
--- a/include/utils/SkEGLContext.h
+++ b/include/utils/SkEGLContext.h
@@ -1,7 +1,9 @@
#ifndef SkEGLContext_DEFINED
#define SkEGLContext_DEFINED
-#if defined(SK_BUILD_FOR_MAC)
+#if defined(SK_MESA)
+ #include "GL/osmesa.h"
+#elif defined(SK_BUILD_FOR_MAC)
#include <AGL/agl.h>
#elif defined(SK_BUILD_FOR_UNIX)
#include <X11/Xlib.h>
@@ -18,10 +20,13 @@ public:
SkEGLContext();
~SkEGLContext();
- bool init(int width, int height);
+ bool init(const int width, const int height);
private:
-#if defined(SK_BUILD_FOR_MAC)
+#if defined(SK_MESA)
+ OSMesaContext context;
+ GLfloat *image;
+#elif defined(SK_BUILD_FOR_MAC)
AGLContext context;
#elif defined(SK_BUILD_FOR_UNIX)
GLXContext context;
diff --git a/src/utils/mesa/SkEGLContext_Mesa.cpp b/src/utils/mesa/SkEGLContext_Mesa.cpp
new file mode 100644
index 0000000000..ed1b7cd451
--- /dev/null
+++ b/src/utils/mesa/SkEGLContext_Mesa.cpp
@@ -0,0 +1,128 @@
+#include "SkEGLContext.h"
+#include "SkTypes.h"
+
+#include "GL/osmesa.h"
+#include "GL/glu.h"
+
+#define SK_GL_DECL_PROC(T, F) T F ## _func = NULL;
+#define SK_GL_GET_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F);
+#define SK_GL_GET_EXT_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F "EXT");
+
+SkEGLContext::SkEGLContext() : context(NULL), image(NULL) {
+}
+
+SkEGLContext::~SkEGLContext() {
+ if (this->image)
+ free(this->image);
+
+ if (this->context)
+ OSMesaDestroyContext(this->context);
+}
+
+#if SK_B32_SHIFT < SK_G32_SHIFT &&\
+ SK_G32_SHIFT < SK_R32_SHIFT &&\
+ SK_R32_SHIFT < SK_A32_SHIFT
+ #define SK_OSMESA_COLOR_ORDER OSMESA_BGRA
+#elif SK_R32_SHIFT < SK_G32_SHIFT &&\
+ SK_G32_SHIFT < SK_B32_SHIFT &&\
+ SK_B32_SHIFT < SK_A32_SHIFT
+ #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
+#elif SK_A32_SHIFT < SK_R32_SHIFT && \
+ SK_R32_SHIFT < SK_G32_SHIFT && \
+ SK_G32_SHIFT < SK_B32_SHIFT
+ #define SK_OSMESA_COLOR_ORDER OSMESA_ARGB
+#else
+ //Color order (rgba) SK_R32_SHIFT SK_G32_SHIFT SK_B32_SHIFT SK_A32_SHIFT
+ #define SK_OSMESA_COLOR_ORDER OSMESA_RGBA
+#endif
+
+bool SkEGLContext::init(const int width, const int height) {
+ /* Create an RGBA-mode context */
+#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
+ /* specify Z, stencil, accum sizes */
+ OSMesaContext ctx = OSMesaCreateContextExt(SK_OSMESA_COLOR_ORDER, 16, 0, 0, NULL);
+#else
+ OSMesaContext ctx = OSMesaCreateContext(SK_OSMESA_COLOR_ORDER, NULL);
+#endif
+ if (!ctx) {
+ SkDebugf("OSMesaCreateContext failed!\n");
+ return false;
+ }
+ this->context = ctx;
+
+ // Allocate the image buffer
+ GLfloat *buffer = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+ if (!buffer) {
+ SkDebugf("Alloc image buffer failed!\n");
+ return false;
+ }
+ this->image = buffer;
+
+ // Bind the buffer to the context and make it current
+ if (!OSMesaMakeCurrent(ctx, buffer, GL_FLOAT, width, height)) {
+ SkDebugf("OSMesaMakeCurrent failed!\n");
+ return false;
+ }
+
+ //Setup the framebuffers
+ SK_GL_DECL_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
+ SK_GL_DECL_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
+ SK_GL_DECL_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
+ SK_GL_DECL_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
+ SK_GL_DECL_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
+ SK_GL_DECL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
+ SK_GL_DECL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
+
+ const GLubyte* glExts = glGetString(GL_EXTENSIONS);
+ if (gluCheckExtension(
+ reinterpret_cast<const GLubyte*>("GL_ARB_framebuffer_object")
+ , glExts))
+ {
+ SK_GL_GET_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
+ SK_GL_GET_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
+ SK_GL_GET_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
+ SK_GL_GET_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
+ SK_GL_GET_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
+ SK_GL_GET_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
+ SK_GL_GET_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
+
+ //osmesa on mac currently only supports EXT
+ } else if (gluCheckExtension(
+ reinterpret_cast<const GLubyte*>("GL_EXT_framebuffer_object")
+ , glExts))
+ {
+ SK_GL_GET_EXT_PROC(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffers)
+ SK_GL_GET_EXT_PROC(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebuffer)
+ SK_GL_GET_EXT_PROC(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
+ SK_GL_GET_EXT_PROC(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
+ SK_GL_GET_EXT_PROC(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
+ SK_GL_GET_EXT_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
+ SK_GL_GET_EXT_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatus)
+ } else {
+ SkDebugf("GL_ARB_framebuffer_object not found.\n");
+ return false;
+ }
+
+ GLuint fboID;
+ GLuint cbID;
+ GLuint dsID;
+ glGenFramebuffers_func(1, &fboID);
+ glBindFramebuffer_func(GL_FRAMEBUFFER, fboID);
+
+ glGenRenderbuffers_func(1, &cbID);
+ glBindRenderbuffer_func(GL_RENDERBUFFER, cbID);
+ glRenderbufferStorage_func(GL_RENDERBUFFER, OSMESA_RGBA, width, height);
+ glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cbID);
+
+ glGenRenderbuffers_func(1, &dsID);
+ glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, dsID);
+ glRenderbufferStorage_func(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
+ glFramebufferRenderbuffer_func(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dsID);
+
+ glViewport(0, 0, width, height);
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+
+ GLenum status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER);
+ return GL_FRAMEBUFFER_COMPLETE == status;
+}