1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/SkGLContextHelper.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,135 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2013 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "gl/SkGLContextHelper.h" 1.12 +#include "GrGLUtil.h" 1.13 + 1.14 +SkGLContextHelper::SkGLContextHelper() 1.15 + : fFBO(0) 1.16 + , fColorBufferID(0) 1.17 + , fDepthStencilBufferID(0) 1.18 + , fGL(NULL) { 1.19 +} 1.20 + 1.21 +SkGLContextHelper::~SkGLContextHelper() { 1.22 + 1.23 + if (fGL) { 1.24 + // TODO: determine why DeleteFramebuffers is generating a GL error in tests 1.25 + SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO)); 1.26 + SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID)); 1.27 + SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID)); 1.28 + } 1.29 + 1.30 + SkSafeUnref(fGL); 1.31 +} 1.32 + 1.33 +bool SkGLContextHelper::init(int width, int height) { 1.34 + if (fGL) { 1.35 + fGL->unref(); 1.36 + this->destroyGLContext(); 1.37 + } 1.38 + 1.39 + fGL = this->createGLContext(); 1.40 + if (fGL) { 1.41 + const GrGLubyte* temp; 1.42 + 1.43 + if (!fGL->validate()) { 1.44 + fGL = NULL; 1.45 + this->destroyGLContext(); 1.46 + return false; 1.47 + } 1.48 + 1.49 + SK_GL_RET(*this, temp, GetString(GR_GL_VERSION)); 1.50 + const char* versionStr = reinterpret_cast<const char*>(temp); 1.51 + GrGLVersion version = GrGLGetVersionFromString(versionStr); 1.52 + 1.53 + // clear any existing GL erorrs 1.54 + GrGLenum error; 1.55 + do { 1.56 + SK_GL_RET(*this, error, GetError()); 1.57 + } while (GR_GL_NO_ERROR != error); 1.58 + 1.59 + SK_GL(*this, GenFramebuffers(1, &fFBO)); 1.60 + SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO)); 1.61 + SK_GL(*this, GenRenderbuffers(1, &fColorBufferID)); 1.62 + SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID)); 1.63 + if (kGLES_GrGLStandard == this->gl()->fStandard) { 1.64 + SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 1.65 + GR_GL_RGBA8, 1.66 + width, height)); 1.67 + } else { 1.68 + SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 1.69 + GR_GL_RGBA, 1.70 + width, height)); 1.71 + } 1.72 + SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1.73 + GR_GL_COLOR_ATTACHMENT0, 1.74 + GR_GL_RENDERBUFFER, 1.75 + fColorBufferID)); 1.76 + SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID)); 1.77 + SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID)); 1.78 + 1.79 + // Some drivers that support packed depth stencil will only succeed 1.80 + // in binding a packed format an FBO. However, we can't rely on packed 1.81 + // depth stencil being available. 1.82 + bool supportsPackedDepthStencil; 1.83 + if (kGLES_GrGLStandard == this->gl()->fStandard) { 1.84 + supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || 1.85 + this->hasExtension("GL_OES_packed_depth_stencil"); 1.86 + } else { 1.87 + supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || 1.88 + this->hasExtension("GL_EXT_packed_depth_stencil") || 1.89 + this->hasExtension("GL_ARB_framebuffer_object"); 1.90 + } 1.91 + 1.92 + if (supportsPackedDepthStencil) { 1.93 + // ES2 requires sized internal formats for RenderbufferStorage 1.94 + // On Desktop we let the driver decide. 1.95 + GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? 1.96 + GR_GL_DEPTH24_STENCIL8 : 1.97 + GR_GL_DEPTH_STENCIL; 1.98 + SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 1.99 + format, 1.100 + width, height)); 1.101 + SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1.102 + GR_GL_DEPTH_ATTACHMENT, 1.103 + GR_GL_RENDERBUFFER, 1.104 + fDepthStencilBufferID)); 1.105 + } else { 1.106 + GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? GR_GL_STENCIL_INDEX8 : 1.107 + GR_GL_STENCIL_INDEX; 1.108 + SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, 1.109 + format, 1.110 + width, height)); 1.111 + } 1.112 + SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1.113 + GR_GL_STENCIL_ATTACHMENT, 1.114 + GR_GL_RENDERBUFFER, 1.115 + fDepthStencilBufferID)); 1.116 + SK_GL(*this, Viewport(0, 0, width, height)); 1.117 + SK_GL(*this, ClearStencil(0)); 1.118 + SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT)); 1.119 + 1.120 + SK_GL_RET(*this, error, GetError()); 1.121 + GrGLenum status; 1.122 + SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1.123 + 1.124 + if (GR_GL_FRAMEBUFFER_COMPLETE != status || 1.125 + GR_GL_NO_ERROR != error) { 1.126 + fFBO = 0; 1.127 + fColorBufferID = 0; 1.128 + fDepthStencilBufferID = 0; 1.129 + fGL->unref(); 1.130 + fGL = NULL; 1.131 + this->destroyGLContext(); 1.132 + return false; 1.133 + } else { 1.134 + return true; 1.135 + } 1.136 + } 1.137 + return false; 1.138 +}