2011-10-19 20:43:20 +00:00
|
|
|
|
|
|
|
/*
|
2013-02-28 20:16:25 +00:00
|
|
|
* Copyright 2013 Google Inc.
|
2011-10-19 20:43:20 +00:00
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
2013-02-28 20:16:25 +00:00
|
|
|
#include "gl/SkGLContextHelper.h"
|
2013-02-26 21:46:32 +00:00
|
|
|
#include "GrGLUtil.h"
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2013-02-28 20:16:25 +00:00
|
|
|
SkGLContextHelper::SkGLContextHelper()
|
2011-10-19 20:43:20 +00:00
|
|
|
: fFBO(0)
|
2012-03-22 20:43:56 +00:00
|
|
|
, fColorBufferID(0)
|
|
|
|
, fDepthStencilBufferID(0)
|
2011-10-19 20:43:20 +00:00
|
|
|
, fGL(NULL) {
|
|
|
|
}
|
|
|
|
|
2013-02-28 20:16:25 +00:00
|
|
|
SkGLContextHelper::~SkGLContextHelper() {
|
2012-03-21 17:57:55 +00:00
|
|
|
|
|
|
|
if (fGL) {
|
2013-02-07 21:16:41 +00:00
|
|
|
// TODO: determine why DeleteFramebuffers is generating a GL error in tests
|
|
|
|
SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO));
|
|
|
|
SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID));
|
|
|
|
SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
|
2012-03-21 17:57:55 +00:00
|
|
|
}
|
|
|
|
|
2011-10-19 20:43:20 +00:00
|
|
|
SkSafeUnref(fGL);
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:36:31 +00:00
|
|
|
bool SkGLContextHelper::init(GrGLStandard forcedGpuAPI, int width,
|
|
|
|
int height) {
|
2011-10-19 20:43:20 +00:00
|
|
|
if (fGL) {
|
|
|
|
fGL->unref();
|
|
|
|
this->destroyGLContext();
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:36:31 +00:00
|
|
|
fGL = this->createGLContext(forcedGpuAPI);
|
2011-10-19 20:43:20 +00:00
|
|
|
if (fGL) {
|
2013-02-07 19:45:46 +00:00
|
|
|
const GrGLubyte* temp;
|
|
|
|
|
2014-01-17 15:05:38 +00:00
|
|
|
if (!fGL->validate()) {
|
2013-02-26 21:46:32 +00:00
|
|
|
fGL = NULL;
|
|
|
|
this->destroyGLContext();
|
|
|
|
return false;
|
|
|
|
}
|
2013-02-07 19:45:46 +00:00
|
|
|
|
|
|
|
SK_GL_RET(*this, temp, GetString(GR_GL_VERSION));
|
|
|
|
const char* versionStr = reinterpret_cast<const char*>(temp);
|
2012-02-09 15:25:13 +00:00
|
|
|
GrGLVersion version = GrGLGetVersionFromString(versionStr);
|
|
|
|
|
2011-12-06 19:54:37 +00:00
|
|
|
// clear any existing GL erorrs
|
|
|
|
GrGLenum error;
|
|
|
|
do {
|
2013-02-07 19:45:46 +00:00
|
|
|
SK_GL_RET(*this, error, GetError());
|
2011-12-06 19:54:37 +00:00
|
|
|
} while (GR_GL_NO_ERROR != error);
|
2012-02-09 15:25:13 +00:00
|
|
|
|
2011-10-19 20:43:20 +00:00
|
|
|
SK_GL(*this, GenFramebuffers(1, &fFBO));
|
|
|
|
SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
|
2012-03-22 20:43:56 +00:00
|
|
|
SK_GL(*this, GenRenderbuffers(1, &fColorBufferID));
|
|
|
|
SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID));
|
2014-01-16 16:35:09 +00:00
|
|
|
if (kGLES_GrGLStandard == this->gl()->fStandard) {
|
2011-12-06 19:54:37 +00:00
|
|
|
SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
|
|
|
|
GR_GL_RGBA8,
|
|
|
|
width, height));
|
|
|
|
} else {
|
|
|
|
SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
|
|
|
|
GR_GL_RGBA,
|
|
|
|
width, height));
|
|
|
|
}
|
2011-10-19 20:43:20 +00:00
|
|
|
SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
|
|
|
GR_GL_COLOR_ATTACHMENT0,
|
2012-08-23 18:09:54 +00:00
|
|
|
GR_GL_RENDERBUFFER,
|
2012-03-22 20:43:56 +00:00
|
|
|
fColorBufferID));
|
|
|
|
SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID));
|
|
|
|
SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID));
|
2012-02-09 15:25:13 +00:00
|
|
|
|
|
|
|
// Some drivers that support packed depth stencil will only succeed
|
|
|
|
// in binding a packed format an FBO. However, we can't rely on packed
|
|
|
|
// depth stencil being available.
|
|
|
|
bool supportsPackedDepthStencil;
|
2014-01-16 16:35:09 +00:00
|
|
|
if (kGLES_GrGLStandard == this->gl()->fStandard) {
|
2013-09-06 15:28:01 +00:00
|
|
|
supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
|
|
|
|
this->hasExtension("GL_OES_packed_depth_stencil");
|
2011-12-06 19:54:37 +00:00
|
|
|
} else {
|
2012-02-09 15:25:13 +00:00
|
|
|
supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
|
2013-02-26 21:46:32 +00:00
|
|
|
this->hasExtension("GL_EXT_packed_depth_stencil") ||
|
|
|
|
this->hasExtension("GL_ARB_framebuffer_object");
|
2012-02-09 15:25:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (supportsPackedDepthStencil) {
|
|
|
|
// ES2 requires sized internal formats for RenderbufferStorage
|
|
|
|
// On Desktop we let the driver decide.
|
2014-01-16 16:35:09 +00:00
|
|
|
GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ?
|
2012-02-09 15:25:13 +00:00
|
|
|
GR_GL_DEPTH24_STENCIL8 :
|
|
|
|
GR_GL_DEPTH_STENCIL;
|
2011-12-06 19:54:37 +00:00
|
|
|
SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
|
2012-02-09 15:25:13 +00:00
|
|
|
format,
|
2011-12-06 19:54:37 +00:00
|
|
|
width, height));
|
|
|
|
SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
|
|
|
GR_GL_DEPTH_ATTACHMENT,
|
|
|
|
GR_GL_RENDERBUFFER,
|
2012-03-22 20:43:56 +00:00
|
|
|
fDepthStencilBufferID));
|
2012-02-09 15:25:13 +00:00
|
|
|
} else {
|
2014-01-16 16:35:09 +00:00
|
|
|
GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? GR_GL_STENCIL_INDEX8 :
|
|
|
|
GR_GL_STENCIL_INDEX;
|
2012-02-09 15:25:13 +00:00
|
|
|
SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
|
|
|
|
format,
|
|
|
|
width, height));
|
2011-12-06 19:54:37 +00:00
|
|
|
}
|
2011-10-19 20:43:20 +00:00
|
|
|
SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
|
|
|
GR_GL_STENCIL_ATTACHMENT,
|
|
|
|
GR_GL_RENDERBUFFER,
|
2012-03-22 20:43:56 +00:00
|
|
|
fDepthStencilBufferID));
|
2011-10-19 20:43:20 +00:00
|
|
|
SK_GL(*this, Viewport(0, 0, width, height));
|
|
|
|
SK_GL(*this, ClearStencil(0));
|
|
|
|
SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
|
2012-08-23 18:09:54 +00:00
|
|
|
|
2013-02-07 19:45:46 +00:00
|
|
|
SK_GL_RET(*this, error, GetError());
|
|
|
|
GrGLenum status;
|
|
|
|
SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
2011-12-06 19:54:37 +00:00
|
|
|
|
|
|
|
if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
|
|
|
|
GR_GL_NO_ERROR != error) {
|
2011-10-19 20:43:20 +00:00
|
|
|
fFBO = 0;
|
2012-03-22 20:43:56 +00:00
|
|
|
fColorBufferID = 0;
|
|
|
|
fDepthStencilBufferID = 0;
|
2011-10-19 20:43:20 +00:00
|
|
|
fGL->unref();
|
|
|
|
fGL = NULL;
|
|
|
|
this->destroyGLContext();
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|