blob: 2d9cd6ac86ca104c4fb62d2c4b097daa25ed9802 [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 */
tomhudson@google.com6bf38b52012-02-14 15:11:59 +00008#include "gl/SkGLContext.h"
bsalomon@google.com373a6632011-10-19 20:43:20 +00009
10SkGLContext::SkGLContext()
11 : fFBO(0)
robertphillips@google.com7c959422012-03-22 20:43:56 +000012 , fColorBufferID(0)
13 , fDepthStencilBufferID(0)
bsalomon@google.com373a6632011-10-19 20:43:20 +000014 , fGL(NULL) {
15}
16
17SkGLContext::~SkGLContext() {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000018
19 if (fGL) {
20 SK_GL(*this, DeleteFramebuffers(1, &fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000021 SK_GL(*this, DeleteRenderbuffers(1, &fColorBufferID));
22 SK_GL(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000023 }
24
bsalomon@google.com373a6632011-10-19 20:43:20 +000025 SkSafeUnref(fGL);
26}
27
bsalomon@google.com6e859372012-02-09 15:25:13 +000028bool SkGLContext::hasExtension(const char* extensionName) const {
29 return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
30}
31
bsalomon@google.com373a6632011-10-19 20:43:20 +000032bool SkGLContext::init(int width, int height) {
33 if (fGL) {
34 fGL->unref();
35 this->destroyGLContext();
36 }
37
38 fGL = this->createGLContext();
39 if (fGL) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000040 fExtensionString =
41 reinterpret_cast<const char*>(SK_GL(*this,
42 GetString(GR_GL_EXTENSIONS)));
43 const char* versionStr =
44 reinterpret_cast<const char*>(SK_GL(*this,
45 GetString(GR_GL_VERSION)));
46 GrGLVersion version = GrGLGetVersionFromString(versionStr);
47
bsalomon@google.com675c5c42011-12-06 19:54:37 +000048 // clear any existing GL erorrs
49 GrGLenum error;
50 do {
51 error = SK_GL(*this, GetError());
52 } while (GR_GL_NO_ERROR != error);
bsalomon@google.com6e859372012-02-09 15:25:13 +000053
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000054 GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
55
bsalomon@google.com373a6632011-10-19 20:43:20 +000056 SK_GL(*this, GenFramebuffers(1, &fFBO));
57 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000058 SK_GL(*this, GenRenderbuffers(1, &fColorBufferID));
59 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID));
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000060 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com675c5c42011-12-06 19:54:37 +000061 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
62 GR_GL_RGBA8,
63 width, height));
64 } else {
65 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
66 GR_GL_RGBA,
67 width, height));
68 }
bsalomon@google.com373a6632011-10-19 20:43:20 +000069 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
70 GR_GL_COLOR_ATTACHMENT0,
71 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +000072 fColorBufferID));
73 SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID));
74 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +000075
76 // Some drivers that support packed depth stencil will only succeed
77 // in binding a packed format an FBO. However, we can't rely on packed
78 // depth stencil being available.
79 bool supportsPackedDepthStencil;
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000080 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000081 supportsPackedDepthStencil =
82 this->hasExtension("GL_OES_packed_depth_stencil");
bsalomon@google.com675c5c42011-12-06 19:54:37 +000083 } else {
bsalomon@google.com6e859372012-02-09 15:25:13 +000084 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
85 this->hasExtension("GL_EXT_packed_depth_stencil") ||
86 this->hasExtension("GL_ARB_framebuffer_object");
87 }
88
89 if (supportsPackedDepthStencil) {
90 // ES2 requires sized internal formats for RenderbufferStorage
91 // On Desktop we let the driver decide.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000092 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +000093 GR_GL_DEPTH24_STENCIL8 :
94 GR_GL_DEPTH_STENCIL;
bsalomon@google.com675c5c42011-12-06 19:54:37 +000095 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
bsalomon@google.com6e859372012-02-09 15:25:13 +000096 format,
bsalomon@google.com675c5c42011-12-06 19:54:37 +000097 width, height));
98 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
99 GR_GL_DEPTH_ATTACHMENT,
100 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000101 fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +0000102 } else {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000103 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +0000104 GR_GL_STENCIL_INDEX8 :
105 GR_GL_STENCIL_INDEX;
106 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
107 format,
108 width, height));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000109 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000110 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
111 GR_GL_STENCIL_ATTACHMENT,
112 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000113 fDepthStencilBufferID));
bsalomon@google.com373a6632011-10-19 20:43:20 +0000114 SK_GL(*this, Viewport(0, 0, width, height));
115 SK_GL(*this, ClearStencil(0));
116 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000117
118 error = SK_GL(*this, GetError());
bsalomon@google.com373a6632011-10-19 20:43:20 +0000119 GrGLenum status =
120 SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000121
122 if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
123 GR_GL_NO_ERROR != error) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000124 fFBO = 0;
robertphillips@google.com7c959422012-03-22 20:43:56 +0000125 fColorBufferID = 0;
126 fDepthStencilBufferID = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +0000127 fGL->unref();
128 fGL = NULL;
129 this->destroyGLContext();
130 return false;
131 } else {
132 return true;
133 }
134 }
135 return false;
136}