blob: 03b70c38f7ea96b005f3a384d56709c1a7ff51e1 [file] [log] [blame]
bsalomon@google.com373a6632011-10-19 20:43:20 +00001
2/*
robertphillips@google.com6177e692013-02-28 20:16:25 +00003 * Copyright 2013 Google Inc.
bsalomon@google.com373a6632011-10-19 20:43:20 +00004 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
bsalomon10805962014-10-08 04:45:09 -07008#include "gl/SkGLContextHelper.h"
bsalomon@google.com1744f972013-02-26 21:46:32 +00009#include "GrGLUtil.h"
bsalomon@google.com373a6632011-10-19 20:43:20 +000010
bsalomon10805962014-10-08 04:45:09 -070011SkGLContextHelper::SkGLContextHelper()
bsalomon@google.com373a6632011-10-19 20:43:20 +000012 : 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
bsalomon10805962014-10-08 04:45:09 -070018SkGLContextHelper::~SkGLContextHelper() {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000019
20 if (fGL) {
robertphillips@google.comedbd21a2013-02-07 21:16:41 +000021 // TODO: determine why DeleteFramebuffers is generating a GL error in tests
22 SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO));
23 SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID));
24 SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID));
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000025 }
26
bsalomon@google.com373a6632011-10-19 20:43:20 +000027 SkSafeUnref(fGL);
28}
29
bsalomon10805962014-10-08 04:45:09 -070030bool SkGLContextHelper::init(GrGLStandard forcedGpuAPI, int width,
kkinnunen80549fc2014-06-30 06:36:31 -070031 int height) {
bsalomon@google.com373a6632011-10-19 20:43:20 +000032 if (fGL) {
33 fGL->unref();
34 this->destroyGLContext();
35 }
36
kkinnunen80549fc2014-06-30 06:36:31 -070037 fGL = this->createGLContext(forcedGpuAPI);
bsalomon@google.com373a6632011-10-19 20:43:20 +000038 if (fGL) {
robertphillips@google.comfe1b5362013-02-07 19:45:46 +000039 const GrGLubyte* temp;
40
commit-bot@chromium.org90313cc2014-01-17 15:05:38 +000041 if (!fGL->validate()) {
bsalomon@google.com1744f972013-02-26 21:46:32 +000042 fGL = NULL;
43 this->destroyGLContext();
44 return false;
45 }
robertphillips@google.comfe1b5362013-02-07 19:45:46 +000046
47 SK_GL_RET(*this, temp, GetString(GR_GL_VERSION));
48 const char* versionStr = reinterpret_cast<const char*>(temp);
bsalomon@google.com6e859372012-02-09 15:25:13 +000049 GrGLVersion version = GrGLGetVersionFromString(versionStr);
50
bsalomon@google.com675c5c42011-12-06 19:54:37 +000051 // clear any existing GL erorrs
52 GrGLenum error;
53 do {
robertphillips@google.comfe1b5362013-02-07 19:45:46 +000054 SK_GL_RET(*this, error, GetError());
bsalomon@google.com675c5c42011-12-06 19:54:37 +000055 } while (GR_GL_NO_ERROR != error);
bsalomon@google.com6e859372012-02-09 15:25:13 +000056
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));
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000061 if (kGLES_GrGLStandard == this->gl()->fStandard) {
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,
rmistry@google.comfbfcd562012-08-23 18:09:54 +000072 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;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000081 if (kGLES_GrGLStandard == this->gl()->fStandard) {
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +000082 supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
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) ||
bsalomon@google.com1744f972013-02-26 21:46:32 +000086 this->hasExtension("GL_EXT_packed_depth_stencil") ||
87 this->hasExtension("GL_ARB_framebuffer_object");
bsalomon@google.com6e859372012-02-09 15:25:13 +000088 }
89
90 if (supportsPackedDepthStencil) {
91 // ES2 requires sized internal formats for RenderbufferStorage
92 // On Desktop we let the driver decide.
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000093 GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ?
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 {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000104 GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? GR_GL_STENCIL_INDEX8 :
105 GR_GL_STENCIL_INDEX;
bsalomon@google.com6e859372012-02-09 15:25:13 +0000106 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));
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000117
robertphillips@google.comfe1b5362013-02-07 19:45:46 +0000118 SK_GL_RET(*this, error, GetError());
119 GrGLenum status;
120 SK_GL_RET(*this, status, 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}
bsalomon944bcf02014-07-29 08:01:52 -0700137
bsalomon10805962014-10-08 04:45:09 -0700138void SkGLContextHelper::testAbandon() {
bsalomon49f085d2014-09-05 13:34:00 -0700139 if (fGL) {
bsalomon944bcf02014-07-29 08:01:52 -0700140 fGL->abandon();
141 }
142}