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 SollenbergerSkGLContextHelper::SkGLContextHelper() 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fFBO(0) 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fColorBufferID(0) 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fDepthStencilBufferID(0) 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fGL(NULL) { 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkGLContextHelper::~SkGLContextHelper() { 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 21096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // TODO: determine why DeleteFramebuffers is generating a GL error in tests 22096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO)); 23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID)); 24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID)); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSafeUnref(fGL); 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool SkGLContextHelper::init(int width, int height) { 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL->unref(); 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->destroyGLContext(); 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL = this->createGLContext(); 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fGL) { 38096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const GrGLubyte* temp; 39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 40096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl()); 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!fGL->validate(bindingInUse) || !fExtensions.init(bindingInUse, fGL)) { 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGL = NULL; 44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->destroyGLContext(); 45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 48096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, temp, GetString(GR_GL_VERSION)); 49096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char* versionStr = reinterpret_cast<const char*>(temp); 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLVersion version = GrGLGetVersionFromString(versionStr); 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // clear any existing GL erorrs 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLenum error; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, error, GetError()); 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (GR_GL_NO_ERROR != error); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenFramebuffers(1, &fFBO)); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO)); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenRenderbuffers(1, &fColorBufferID)); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID)); 620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (kES_GrGLBinding == bindingInUse) { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RGBA8, 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RGBA, 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_COLOR_ATTACHMENT0, 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColorBufferID)); 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID)); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID)); 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Some drivers that support packed depth stencil will only succeed 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // in binding a packed format an FBO. However, we can't rely on packed 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // depth stencil being available. 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool supportsPackedDepthStencil; 820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (kES_GrGLBinding == bindingInUse) { 830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || 840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger this->hasExtension("GL_OES_packed_depth_stencil"); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || 87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->hasExtension("GL_EXT_packed_depth_stencil") || 88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->hasExtension("GL_ARB_framebuffer_object"); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (supportsPackedDepthStencil) { 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // ES2 requires sized internal formats for RenderbufferStorage 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // On Desktop we let the driver decide. 940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger GrGLenum format = kES_GrGLBinding == bindingInUse ? 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH24_STENCIL8 : 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH_STENCIL; 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru format, 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_DEPTH_ATTACHMENT, 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID)); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger GrGLenum format = kES_GrGLBinding == bindingInUse ? 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_INDEX8 : 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_INDEX; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru format, 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height)); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_STENCIL_ATTACHMENT, 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_RENDERBUFFER, 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID)); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, Viewport(0, 0, width, height)); 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, ClearStencil(0)); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT)); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, error, GetError()); 121096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLenum status; 122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GR_GL_FRAMEBUFFER_COMPLETE != status || 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_GL_NO_ERROR != error) { 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFBO = 0; 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fColorBufferID = 0; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDepthStencilBufferID = 0; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL->unref(); 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGL = NULL; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->destroyGLContext(); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 139