1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "gl/SkGLContext.h"
9
SkGLContext()10 SkGLContext::SkGLContext()
11 : fFBO(0)
12 , fGL(NULL) {
13 }
14
~SkGLContext()15 SkGLContext::~SkGLContext() {
16 SkSafeUnref(fGL);
17 }
18
hasExtension(const char * extensionName) const19 bool SkGLContext::hasExtension(const char* extensionName) const {
20 return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
21 }
22
init(int width,int height)23 bool SkGLContext::init(int width, int height) {
24 if (fGL) {
25 fGL->unref();
26 this->destroyGLContext();
27 }
28
29 fGL = this->createGLContext();
30 if (fGL) {
31 fExtensionString =
32 reinterpret_cast<const char*>(SK_GL(*this,
33 GetString(GR_GL_EXTENSIONS)));
34 const char* versionStr =
35 reinterpret_cast<const char*>(SK_GL(*this,
36 GetString(GR_GL_VERSION)));
37 GrGLVersion version = GrGLGetVersionFromString(versionStr);
38
39 // clear any existing GL erorrs
40 GrGLenum error;
41 do {
42 error = SK_GL(*this, GetError());
43 } while (GR_GL_NO_ERROR != error);
44
45 GrGLuint cbID;
46 GrGLuint dsID;
47
48 GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
49
50 SK_GL(*this, GenFramebuffers(1, &fFBO));
51 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
52 SK_GL(*this, GenRenderbuffers(1, &cbID));
53 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, cbID));
54 if (kES2_GrGLBinding == bindingInUse) {
55 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
56 GR_GL_RGBA8,
57 width, height));
58 } else {
59 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
60 GR_GL_RGBA,
61 width, height));
62 }
63 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
64 GR_GL_COLOR_ATTACHMENT0,
65 GR_GL_RENDERBUFFER,
66 cbID));
67 SK_GL(*this, GenRenderbuffers(1, &dsID));
68 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, dsID));
69
70 // Some drivers that support packed depth stencil will only succeed
71 // in binding a packed format an FBO. However, we can't rely on packed
72 // depth stencil being available.
73 bool supportsPackedDepthStencil;
74 if (kES2_GrGLBinding == bindingInUse) {
75 supportsPackedDepthStencil =
76 this->hasExtension("GL_OES_packed_depth_stencil");
77 } else {
78 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
79 this->hasExtension("GL_EXT_packed_depth_stencil") ||
80 this->hasExtension("GL_ARB_framebuffer_object");
81 }
82
83 if (supportsPackedDepthStencil) {
84 // ES2 requires sized internal formats for RenderbufferStorage
85 // On Desktop we let the driver decide.
86 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
87 GR_GL_DEPTH24_STENCIL8 :
88 GR_GL_DEPTH_STENCIL;
89 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
90 format,
91 width, height));
92 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
93 GR_GL_DEPTH_ATTACHMENT,
94 GR_GL_RENDERBUFFER,
95 dsID));
96 } else {
97 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
98 GR_GL_STENCIL_INDEX8 :
99 GR_GL_STENCIL_INDEX;
100 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
101 format,
102 width, height));
103 }
104 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
105 GR_GL_STENCIL_ATTACHMENT,
106 GR_GL_RENDERBUFFER,
107 dsID));
108 SK_GL(*this, Viewport(0, 0, width, height));
109 SK_GL(*this, ClearStencil(0));
110 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
111
112 error = SK_GL(*this, GetError());
113 GrGLenum status =
114 SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
115
116 if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
117 GR_GL_NO_ERROR != error) {
118 fFBO = 0;
119 fGL->unref();
120 fGL = NULL;
121 this->destroyGLContext();
122 return false;
123 } else {
124 return true;
125 }
126 }
127 return false;
128 }
129