OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2013 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 #include "GrGLUtil.h" | |
10 | |
11 SkGLContext::SkGLContext() | |
12 : fFBO(0) | |
13 , fColorBufferID(0) | |
14 , fDepthStencilBufferID(0) | |
15 , fGL(NULL) { | |
16 } | |
17 | |
18 SkGLContext::~SkGLContext() { | |
19 | |
20 if (fGL) { | |
21 // TODO: determine why DeleteFramebuffers is generating a GL error in te
sts | |
22 SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO)); | |
23 SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID)); | |
24 SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID)); | |
25 } | |
26 | |
27 SkSafeUnref(fGL); | |
28 } | |
29 | |
30 bool SkGLContext::init(GrGLStandard forcedGpuAPI, int width, | |
31 int height) { | |
32 if (fGL) { | |
33 fGL->unref(); | |
34 this->destroyGLContext(); | |
35 } | |
36 | |
37 fGL = this->createGLContext(forcedGpuAPI); | |
38 if (fGL) { | |
39 const GrGLubyte* temp; | |
40 | |
41 if (!fGL->validate()) { | |
42 fGL = NULL; | |
43 this->destroyGLContext(); | |
44 return false; | |
45 } | |
46 | |
47 SK_GL_RET(*this, temp, GetString(GR_GL_VERSION)); | |
48 const char* versionStr = reinterpret_cast<const char*>(temp); | |
49 GrGLVersion version = GrGLGetVersionFromString(versionStr); | |
50 | |
51 // clear any existing GL erorrs | |
52 GrGLenum error; | |
53 do { | |
54 SK_GL_RET(*this, error, GetError()); | |
55 } while (GR_GL_NO_ERROR != error); | |
56 | |
57 SK_GL(*this, GenFramebuffers(1, &fFBO)); | |
58 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO)); | |
59 SK_GL(*this, GenRenderbuffers(1, &fColorBufferID)); | |
60 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID)); | |
61 if (kGLES_GrGLStandard == this->gl()->fStandard) { | |
62 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, | |
63 GR_GL_RGBA8, | |
64 width, height)); | |
65 } else { | |
66 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, | |
67 GR_GL_RGBA, | |
68 width, height)); | |
69 } | |
70 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | |
71 GR_GL_COLOR_ATTACHMENT0, | |
72 GR_GL_RENDERBUFFER, | |
73 fColorBufferID)); | |
74 SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID)); | |
75 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID)
); | |
76 | |
77 // Some drivers that support packed depth stencil will only succeed | |
78 // in binding a packed format an FBO. However, we can't rely on packed | |
79 // depth stencil being available. | |
80 bool supportsPackedDepthStencil; | |
81 if (kGLES_GrGLStandard == this->gl()->fStandard) { | |
82 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || | |
83 this->hasExtension("GL_OES_packed_depth
_stencil"); | |
84 } else { | |
85 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || | |
86 this->hasExtension("GL_EXT_packed_depth
_stencil") || | |
87 this->hasExtension("GL_ARB_framebuffer_
object"); | |
88 } | |
89 | |
90 if (supportsPackedDepthStencil) { | |
91 // ES2 requires sized internal formats for RenderbufferStorage | |
92 // On Desktop we let the driver decide. | |
93 GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? | |
94 GR_GL_DEPTH24_STENCIL8 : | |
95 GR_GL_DEPTH_STENCIL; | |
96 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, | |
97 format, | |
98 width, height)); | |
99 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | |
100 GR_GL_DEPTH_ATTACHMENT, | |
101 GR_GL_RENDERBUFFER, | |
102 fDepthStencilBufferID)); | |
103 } else { | |
104 GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? GR_G
L_STENCIL_INDEX8 : | |
105 GR_GL_
STENCIL_INDEX; | |
106 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, | |
107 format, | |
108 width, height)); | |
109 } | |
110 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | |
111 GR_GL_STENCIL_ATTACHMENT, | |
112 GR_GL_RENDERBUFFER, | |
113 fDepthStencilBufferID)); | |
114 SK_GL(*this, Viewport(0, 0, width, height)); | |
115 SK_GL(*this, ClearStencil(0)); | |
116 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT)); | |
117 | |
118 SK_GL_RET(*this, error, GetError()); | |
119 GrGLenum status; | |
120 SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | |
121 | |
122 if (GR_GL_FRAMEBUFFER_COMPLETE != status || | |
123 GR_GL_NO_ERROR != error) { | |
124 fFBO = 0; | |
125 fColorBufferID = 0; | |
126 fDepthStencilBufferID = 0; | |
127 fGL->unref(); | |
128 fGL = NULL; | |
129 this->destroyGLContext(); | |
130 return false; | |
131 } else { | |
132 return true; | |
133 } | |
134 } | |
135 return false; | |
136 } | |
137 | |
138 void SkGLContext::testAbandon() { | |
139 if (fGL) { | |
140 fGL->abandon(); | |
141 } | |
142 } | |
OLD | NEW |