180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 3096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Copyright 2013 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 8096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/SkGLContextHelper.h" 9096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "GrGLUtil.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSK_DEFINE_INST_COUNT(SkGLContextHelper) 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkGLContextHelper::SkGLContextHelper() 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fFBO(0) 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fColorBufferID(0) 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fDepthStencilBufferID(0) 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fGL(NULL) { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkGLContextHelper::~SkGLContextHelper() { 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // TODO: determine why DeleteFramebuffers is generating a GL error in tests 24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO)); 25096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID)); 26096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID)); 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSafeUnref(fGL); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool SkGLContextHelper::init(int width, int height) { 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL->unref(); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->destroyGLContext(); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL = this->createGLContext(); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 40096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const GrGLubyte* temp; 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl()); 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!fGL->validate(bindingInUse) || !fExtensions.init(bindingInUse, fGL)) { 45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGL = NULL; 46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->destroyGLContext(); 47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 48096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 49096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 50096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, temp, GetString(GR_GL_VERSION)); 51096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char* versionStr = reinterpret_cast<const char*>(temp); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLVersion version = GrGLGetVersionFromString(versionStr); 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // clear any existing GL erorrs 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLenum error; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 57096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, error, GetError()); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (GR_GL_NO_ERROR != error); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenFramebuffers(1, &fFBO)); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO)); 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenRenderbuffers(1, &fColorBufferID)); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID)); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kES2_GrGLBinding == bindingInUse) { 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RGBA8, 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RGBA, 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_COLOR_ATTACHMENT0, 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColorBufferID)); 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID)); 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID)); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Some drivers that support packed depth stencil will only succeed 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // in binding a packed format an FBO. However, we can't rely on packed 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // depth stencil being available. 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool supportsPackedDepthStencil; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kES2_GrGLBinding == bindingInUse) { 85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger supportsPackedDepthStencil = this->hasExtension("GL_OES_packed_depth_stencil"); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || 88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->hasExtension("GL_EXT_packed_depth_stencil") || 89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->hasExtension("GL_ARB_framebuffer_object"); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (supportsPackedDepthStencil) { 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // ES2 requires sized internal formats for RenderbufferStorage 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // On Desktop we let the driver decide. 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLenum format = kES2_GrGLBinding == bindingInUse ? 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH24_STENCIL8 : 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH_STENCIL; 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru format, 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH_ATTACHMENT, 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID)); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLenum format = kES2_GrGLBinding == bindingInUse ? 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_INDEX8 : 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_INDEX; 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru format, 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_ATTACHMENT, 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID)); 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, Viewport(0, 0, width, height)); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, ClearStencil(0)); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT)); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, error, GetError()); 122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLenum status; 123096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GR_GL_FRAMEBUFFER_COMPLETE != status || 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_NO_ERROR != error) { 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFBO = 0; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColorBufferID = 0; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID = 0; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL->unref(); 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL = NULL; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->destroyGLContext(); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 140