blob: f67e68cc54a0a1103ec0623f7274ccc596657ba6 [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.com9c1f1ac2012-05-07 17:09:37 +00009#include "gl/GrGLUtil.h"
bsalomon@google.com373a6632011-10-19 20:43:20 +000010
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000011SK_DEFINE_INST_COUNT(SkGLContext)
12
bsalomon@google.com373a6632011-10-19 20:43:20 +000013SkGLContext::SkGLContext()
14 : fFBO(0)
robertphillips@google.com7c959422012-03-22 20:43:56 +000015 , fColorBufferID(0)
16 , fDepthStencilBufferID(0)
bsalomon@google.com373a6632011-10-19 20:43:20 +000017 , fGL(NULL) {
18}
19
20SkGLContext::~SkGLContext() {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000021
22 if (fGL) {
23 SK_GL(*this, DeleteFramebuffers(1, &fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000024 SK_GL(*this, DeleteRenderbuffers(1, &fColorBufferID));
25 SK_GL(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000026 }
27
bsalomon@google.com373a6632011-10-19 20:43:20 +000028 SkSafeUnref(fGL);
29}
30
bsalomon@google.com6e859372012-02-09 15:25:13 +000031bool SkGLContext::hasExtension(const char* extensionName) const {
32 return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
33}
34
bsalomon@google.com373a6632011-10-19 20:43:20 +000035bool SkGLContext::init(int width, int height) {
36 if (fGL) {
37 fGL->unref();
38 this->destroyGLContext();
39 }
40
41 fGL = this->createGLContext();
42 if (fGL) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000043 fExtensionString =
44 reinterpret_cast<const char*>(SK_GL(*this,
45 GetString(GR_GL_EXTENSIONS)));
46 const char* versionStr =
47 reinterpret_cast<const char*>(SK_GL(*this,
48 GetString(GR_GL_VERSION)));
49 GrGLVersion version = GrGLGetVersionFromString(versionStr);
50
bsalomon@google.com675c5c42011-12-06 19:54:37 +000051 // clear any existing GL erorrs
52 GrGLenum error;
53 do {
54 error = SK_GL(*this, GetError());
55 } while (GR_GL_NO_ERROR != error);
bsalomon@google.com6e859372012-02-09 15:25:13 +000056
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000057 GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
58
bsalomon@google.com373a6632011-10-19 20:43:20 +000059 SK_GL(*this, GenFramebuffers(1, &fFBO));
60 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000061 SK_GL(*this, GenRenderbuffers(1, &fColorBufferID));
62 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID));
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000063 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com675c5c42011-12-06 19:54:37 +000064 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
65 GR_GL_RGBA8,
66 width, height));
67 } else {
68 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
69 GR_GL_RGBA,
70 width, height));
71 }
bsalomon@google.com373a6632011-10-19 20:43:20 +000072 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
73 GR_GL_COLOR_ATTACHMENT0,
74 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +000075 fColorBufferID));
76 SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID));
77 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +000078
79 // Some drivers that support packed depth stencil will only succeed
80 // in binding a packed format an FBO. However, we can't rely on packed
81 // depth stencil being available.
82 bool supportsPackedDepthStencil;
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000083 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000084 supportsPackedDepthStencil =
85 this->hasExtension("GL_OES_packed_depth_stencil");
bsalomon@google.com675c5c42011-12-06 19:54:37 +000086 } else {
bsalomon@google.com6e859372012-02-09 15:25:13 +000087 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
88 this->hasExtension("GL_EXT_packed_depth_stencil") ||
89 this->hasExtension("GL_ARB_framebuffer_object");
90 }
91
92 if (supportsPackedDepthStencil) {
93 // ES2 requires sized internal formats for RenderbufferStorage
94 // On Desktop we let the driver decide.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000095 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +000096 GR_GL_DEPTH24_STENCIL8 :
97 GR_GL_DEPTH_STENCIL;
bsalomon@google.com675c5c42011-12-06 19:54:37 +000098 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
bsalomon@google.com6e859372012-02-09 15:25:13 +000099 format,
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000100 width, height));
101 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
102 GR_GL_DEPTH_ATTACHMENT,
103 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000104 fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +0000105 } else {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000106 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +0000107 GR_GL_STENCIL_INDEX8 :
108 GR_GL_STENCIL_INDEX;
109 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
110 format,
111 width, height));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000112 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000113 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
114 GR_GL_STENCIL_ATTACHMENT,
115 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000116 fDepthStencilBufferID));
bsalomon@google.com373a6632011-10-19 20:43:20 +0000117 SK_GL(*this, Viewport(0, 0, width, height));
118 SK_GL(*this, ClearStencil(0));
119 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000120
121 error = SK_GL(*this, GetError());
bsalomon@google.com373a6632011-10-19 20:43:20 +0000122 GrGLenum status =
123 SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000124
125 if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
126 GR_GL_NO_ERROR != error) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000127 fFBO = 0;
robertphillips@google.com7c959422012-03-22 20:43:56 +0000128 fColorBufferID = 0;
129 fDepthStencilBufferID = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +0000130 fGL->unref();
131 fGL = NULL;
132 this->destroyGLContext();
133 return false;
134 } else {
135 return true;
136 }
137 }
138 return false;
139}