blob: 3252b566a6612b81ce76c2f905da1c510f426545 [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
11SkGLContext::SkGLContext()
12 : fFBO(0)
robertphillips@google.com7c959422012-03-22 20:43:56 +000013 , fColorBufferID(0)
14 , fDepthStencilBufferID(0)
bsalomon@google.com373a6632011-10-19 20:43:20 +000015 , fGL(NULL) {
16}
17
18SkGLContext::~SkGLContext() {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000019
20 if (fGL) {
21 SK_GL(*this, DeleteFramebuffers(1, &fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000022 SK_GL(*this, DeleteRenderbuffers(1, &fColorBufferID));
23 SK_GL(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000024 }
25
bsalomon@google.com373a6632011-10-19 20:43:20 +000026 SkSafeUnref(fGL);
27}
28
bsalomon@google.com6e859372012-02-09 15:25:13 +000029bool SkGLContext::hasExtension(const char* extensionName) const {
30 return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
31}
32
bsalomon@google.com373a6632011-10-19 20:43:20 +000033bool SkGLContext::init(int width, int height) {
34 if (fGL) {
35 fGL->unref();
36 this->destroyGLContext();
37 }
38
39 fGL = this->createGLContext();
40 if (fGL) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000041 fExtensionString =
42 reinterpret_cast<const char*>(SK_GL(*this,
43 GetString(GR_GL_EXTENSIONS)));
44 const char* versionStr =
45 reinterpret_cast<const char*>(SK_GL(*this,
46 GetString(GR_GL_VERSION)));
47 GrGLVersion version = GrGLGetVersionFromString(versionStr);
48
bsalomon@google.com675c5c42011-12-06 19:54:37 +000049 // clear any existing GL erorrs
50 GrGLenum error;
51 do {
52 error = SK_GL(*this, GetError());
53 } while (GR_GL_NO_ERROR != error);
bsalomon@google.com6e859372012-02-09 15:25:13 +000054
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000055 GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
56
bsalomon@google.com373a6632011-10-19 20:43:20 +000057 SK_GL(*this, GenFramebuffers(1, &fFBO));
58 SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
robertphillips@google.com7c959422012-03-22 20:43:56 +000059 SK_GL(*this, GenRenderbuffers(1, &fColorBufferID));
60 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID));
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000061 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com675c5c42011-12-06 19:54:37 +000062 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 }
bsalomon@google.com373a6632011-10-19 20:43:20 +000070 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
71 GR_GL_COLOR_ATTACHMENT0,
72 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +000073 fColorBufferID));
74 SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID));
75 SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +000076
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;
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000081 if (kES2_GrGLBinding == bindingInUse) {
bsalomon@google.com6e859372012-02-09 15:25:13 +000082 supportsPackedDepthStencil =
83 this->hasExtension("GL_OES_packed_depth_stencil");
bsalomon@google.com675c5c42011-12-06 19:54:37 +000084 } else {
bsalomon@google.com6e859372012-02-09 15:25:13 +000085 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.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000093 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +000094 GR_GL_DEPTH24_STENCIL8 :
95 GR_GL_DEPTH_STENCIL;
bsalomon@google.com675c5c42011-12-06 19:54:37 +000096 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
bsalomon@google.com6e859372012-02-09 15:25:13 +000097 format,
bsalomon@google.com675c5c42011-12-06 19:54:37 +000098 width, height));
99 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
100 GR_GL_DEPTH_ATTACHMENT,
101 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000102 fDepthStencilBufferID));
bsalomon@google.com6e859372012-02-09 15:25:13 +0000103 } else {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000104 GrGLenum format = kES2_GrGLBinding == bindingInUse ?
bsalomon@google.com6e859372012-02-09 15:25:13 +0000105 GR_GL_STENCIL_INDEX8 :
106 GR_GL_STENCIL_INDEX;
107 SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER,
108 format,
109 width, height));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000110 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000111 SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
112 GR_GL_STENCIL_ATTACHMENT,
113 GR_GL_RENDERBUFFER,
robertphillips@google.com7c959422012-03-22 20:43:56 +0000114 fDepthStencilBufferID));
bsalomon@google.com373a6632011-10-19 20:43:20 +0000115 SK_GL(*this, Viewport(0, 0, width, height));
116 SK_GL(*this, ClearStencil(0));
117 SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000118
119 error = SK_GL(*this, GetError());
bsalomon@google.com373a6632011-10-19 20:43:20 +0000120 GrGLenum status =
121 SK_GL(*this, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
bsalomon@google.com675c5c42011-12-06 19:54:37 +0000122
123 if (GR_GL_FRAMEBUFFER_COMPLETE != status ||
124 GR_GL_NO_ERROR != error) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000125 fFBO = 0;
robertphillips@google.com7c959422012-03-22 20:43:56 +0000126 fColorBufferID = 0;
127 fDepthStencilBufferID = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +0000128 fGL->unref();
129 fGL = NULL;
130 this->destroyGLContext();
131 return false;
132 } else {
133 return true;
134 }
135 }
136 return false;
137}