blob: 7ac2ede7cafc9839a00ecff51befe5ceec8fc0bc [file] [log] [blame]
bsalomon@google.com373a6632011-10-19 20:43:20 +00001
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 "SkGLContext.h"
9
10SkGLContext::SkGLContext()
11 : fFBO(0)
12 , fGL(NULL) {
13}
14
15SkGLContext::~SkGLContext() {
16 SkSafeUnref(fGL);
17}
18
bsalomon@google.com6e859372012-02-09 15:25:13 +000019bool SkGLContext::hasExtension(const char* extensionName) const {
20 return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
21}
22
bsalomon@google.com373a6632011-10-19 20:43:20 +000023bool SkGLContext::init(int width, int height) {
24 if (fGL) {
25 fGL->unref();
26 this->destroyGLContext();
27 }
28
29 fGL = this->createGLContext();
30 if (fGL) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000031 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
bsalomon@google.com675c5c42011-12-06 19:54:37 +000039 // clear any existing GL erorrs
40 GrGLenum error;
41 do {
42 error = SK_GL(*this, GetError());
43 } while (GR_GL_NO_ERROR != error);
bsalomon@google.com6e859372012-02-09 15:25:13 +000044
bsalomon@google.com373a6632011-10-19 20:43:20 +000045 GrGLuint cbID;
46 GrGLuint dsID;
bsalomon@google.com6e859372012-02-09 15:25:13 +000047
bsalomon@google.com373a6632011-10-19 20:43:20 +000048 SK_GL(*this, GenFramebuffers(1, &fFBO));
49 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
50 SK_GL(*this, GenRenderbuffers(1, &cbID));
51 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, cbID));
bsalomon@google.com675c5c42011-12-06 19:54:37 +000052 if (fGL->supportsES2()) {
53 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
54 GR_GL_RGBA8,
55 width, height));
56 } else {
57 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
58 GR_GL_RGBA,
59 width, height));
60 }
bsalomon@google.com373a6632011-10-19 20:43:20 +000061 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
62 GR_GL_COLOR_ATTACHMENT0,
63 GR_GL_RENDERBUFFER,
64 cbID));
65 SK_GL(*this, GenRenderbuffers(1, &dsID));
66 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, dsID));
bsalomon@google.com6e859372012-02-09 15:25:13 +000067
68 // Some drivers that support packed depth stencil will only succeed
69 // in binding a packed format an FBO. However, we can't rely on packed
70 // depth stencil being available.
71 bool supportsPackedDepthStencil;
bsalomon@google.com675c5c42011-12-06 19:54:37 +000072 if (fGL->supportsES2()) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000073 supportsPackedDepthStencil =
74 this->hasExtension("GL_OES_packed_depth_stencil");
bsalomon@google.com675c5c42011-12-06 19:54:37 +000075 } else {
bsalomon@google.com6e859372012-02-09 15:25:13 +000076 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
77 this->hasExtension("GL_EXT_packed_depth_stencil") ||
78 this->hasExtension("GL_ARB_framebuffer_object");
79 }
80
81 if (supportsPackedDepthStencil) {
82 // ES2 requires sized internal formats for RenderbufferStorage
83 // On Desktop we let the driver decide.
84 GrGLenum format = fGL->supportsES2() ?
85 GR_GL_DEPTH24_STENCIL8 :
86 GR_GL_DEPTH_STENCIL;
bsalomon@google.com675c5c42011-12-06 19:54:37 +000087 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
bsalomon@google.com6e859372012-02-09 15:25:13 +000088 format,
bsalomon@google.com675c5c42011-12-06 19:54:37 +000089 width, height));
90 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
91 GR_GL_DEPTH_ATTACHMENT,
92 GR_GL_RENDERBUFFER,
93 dsID));
bsalomon@google.com6e859372012-02-09 15:25:13 +000094 } else {
95 GrGLenum format = fGL->supportsES2() ?
96 GR_GL_STENCIL_INDEX8 :
97 GR_GL_STENCIL_INDEX;
98 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
99 format,
100 width, height));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000101 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000102 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
103 GR_GL_STENCIL_ATTACHMENT,
104 GR_GL_RENDERBUFFER,
105 dsID));
106 SK_GL(*this, Viewport(0, 0, width, height));
107 SK_GL(*this, ClearStencil(0));
108 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000109
110 error = SK_GL(*this, GetError());
bsalomon@google.com373a6632011-10-19 20:43:20 +0000111 GrGLenum status =
112 SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000113
114 if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
115 GR_GL_NO_ERROR != error) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000116 fFBO = 0;
117 fGL->unref();
118 fGL = NULL;
119 this->destroyGLContext();
120 return false;
121 } else {
122 return true;
123 }
124 }
125 return false;
126}