1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gl/scoped_binders.h"
6 #include "ui/gl/gl_bindings.h"
7 #include "ui/gl/gl_context.h"
8 #include "ui/gl/gl_state_restorer.h"
9
10 namespace gl {
11
ScopedFramebufferBinder(unsigned int fbo)12 ScopedFramebufferBinder::ScopedFramebufferBinder(unsigned int fbo)
13 : state_restorer_(!GLContext::GetCurrent()
14 ? NULL
15 : GLContext::GetCurrent()->GetGLStateRestorer()),
16 old_fbo_(-1) {
17 if (!state_restorer_)
18 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo_);
19 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
20 }
21
~ScopedFramebufferBinder()22 ScopedFramebufferBinder::~ScopedFramebufferBinder() {
23 if (state_restorer_) {
24 DCHECK(!!GLContext::GetCurrent());
25 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
26 state_restorer_->RestoreFramebufferBindings();
27 } else {
28 glBindFramebufferEXT(GL_FRAMEBUFFER, old_fbo_);
29 }
30 }
31
ScopedActiveTexture(unsigned int texture)32 ScopedActiveTexture::ScopedActiveTexture(unsigned int texture)
33 : state_restorer_(!GLContext::GetCurrent()
34 ? NULL
35 : GLContext::GetCurrent()->GetGLStateRestorer()),
36 old_texture_(-1) {
37 if (!state_restorer_)
38 glGetIntegerv(GL_ACTIVE_TEXTURE, &old_texture_);
39 glActiveTexture(texture);
40 }
41
~ScopedActiveTexture()42 ScopedActiveTexture::~ScopedActiveTexture() {
43 if (state_restorer_) {
44 DCHECK(!!GLContext::GetCurrent());
45 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
46 state_restorer_->RestoreActiveTexture();
47 } else {
48 glActiveTexture(old_texture_);
49 }
50 }
51
ScopedTextureBinder(unsigned int target,unsigned int id)52 ScopedTextureBinder::ScopedTextureBinder(unsigned int target, unsigned int id)
53 : state_restorer_(!GLContext::GetCurrent()
54 ? NULL
55 : GLContext::GetCurrent()->GetGLStateRestorer()),
56 target_(target),
57 old_id_(-1) {
58 if (!state_restorer_) {
59 GLenum target_getter = 0;
60 switch (target) {
61 case GL_TEXTURE_2D:
62 target_getter = GL_TEXTURE_BINDING_2D;
63 break;
64 case GL_TEXTURE_CUBE_MAP:
65 target_getter = GL_TEXTURE_BINDING_CUBE_MAP;
66 break;
67 case GL_TEXTURE_EXTERNAL_OES:
68 target_getter = GL_TEXTURE_BINDING_EXTERNAL_OES;
69 break;
70 case GL_TEXTURE_RECTANGLE_ARB:
71 target_getter = GL_TEXTURE_BINDING_RECTANGLE_ARB;
72 break;
73 default:
74 NOTIMPLEMENTED() << " Target not supported.";
75 }
76 glGetIntegerv(target_getter, &old_id_);
77 }
78 glBindTexture(target_, id);
79 }
80
~ScopedTextureBinder()81 ScopedTextureBinder::~ScopedTextureBinder() {
82 if (state_restorer_) {
83 DCHECK(!!GLContext::GetCurrent());
84 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
85 state_restorer_->RestoreActiveTextureUnitBinding(target_);
86 } else {
87 glBindTexture(target_, old_id_);
88 }
89 }
90
ScopedUseProgram(unsigned int program)91 ScopedUseProgram::ScopedUseProgram(unsigned int program)
92 : state_restorer_(!GLContext::GetCurrent()
93 ? NULL
94 : GLContext::GetCurrent()->GetGLStateRestorer()),
95 old_program_(-1) {
96 if (!state_restorer_)
97 glGetIntegerv(GL_CURRENT_PROGRAM, &old_program_);
98 glUseProgram(program);
99 }
100
~ScopedUseProgram()101 ScopedUseProgram::~ScopedUseProgram() {
102 if (state_restorer_) {
103 DCHECK(!!GLContext::GetCurrent());
104 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
105 state_restorer_->RestoreProgramBindings();
106 } else {
107 glUseProgram(old_program_);
108 }
109 }
110
ScopedVertexAttribArray(unsigned int index,int size,unsigned int type,char normalized,int stride,const void * pointer)111 ScopedVertexAttribArray::ScopedVertexAttribArray(unsigned int index,
112 int size,
113 unsigned int type,
114 char normalized,
115 int stride,
116 const void* pointer)
117 : state_restorer_(!GLContext::GetCurrent()
118 ? NULL
119 : GLContext::GetCurrent()->GetGLStateRestorer()),
120 buffer_(0),
121 enabled_(GL_FALSE),
122 index_(index),
123 size_(-1),
124 type_(-1),
125 normalized_(GL_FALSE),
126 stride_(0),
127 pointer_(0) {
128 if (!state_restorer_) {
129 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_);
130 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled_);
131 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size_);
132 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type_);
133 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized_);
134 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride_);
135 glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pointer_);
136 }
137
138 glEnableVertexAttribArray(index);
139 glVertexAttribPointer(index, size, type, normalized, stride, pointer);
140 }
141
~ScopedVertexAttribArray()142 ScopedVertexAttribArray::~ScopedVertexAttribArray() {
143 if (state_restorer_) {
144 DCHECK(!!GLContext::GetCurrent());
145 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
146 state_restorer_->RestoreVertexAttribArray(index_);
147 } else {
148 ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, buffer_);
149 glVertexAttribPointer(index_, size_, type_, normalized_, stride_, pointer_);
150 if (enabled_ == GL_FALSE)
151 glDisableVertexAttribArray(index_);
152 }
153 }
154
ScopedBufferBinder(unsigned int target,unsigned int id)155 ScopedBufferBinder::ScopedBufferBinder(unsigned int target, unsigned int id)
156 : state_restorer_(!GLContext::GetCurrent()
157 ? NULL
158 : GLContext::GetCurrent()->GetGLStateRestorer()),
159 target_(target),
160 old_id_(-1) {
161 if (!state_restorer_) {
162 GLenum target_getter = 0;
163 switch (target) {
164 case GL_ARRAY_BUFFER:
165 target_getter = GL_ARRAY_BUFFER_BINDING;
166 break;
167 case GL_PIXEL_UNPACK_BUFFER:
168 target_getter = GL_PIXEL_UNPACK_BUFFER_BINDING;
169 break;
170 default:
171 NOTIMPLEMENTED() << " Target not supported.";
172 }
173 glGetIntegerv(target_getter, &old_id_);
174 }
175 glBindBuffer(target_, id);
176 }
177
~ScopedBufferBinder()178 ScopedBufferBinder::~ScopedBufferBinder() {
179 if (state_restorer_) {
180 DCHECK(!!GLContext::GetCurrent());
181 DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
182 state_restorer_->RestoreBufferBinding(target_);
183 } else {
184 glBindBuffer(target_, old_id_);
185 }
186 }
187
ScopedViewport(int x,int y,int width,int height)188 ScopedViewport::ScopedViewport(int x, int y, int width, int height) {
189 glGetIntegerv(GL_VIEWPORT, data_);
190 glViewport(x, y, width, height);
191 }
192
~ScopedViewport()193 ScopedViewport::~ScopedViewport() {
194 glViewport(data_[0], data_[1], data_[2], data_[3]);
195 }
196
ScopedColorMask(char red,char green,char blue,char alpha)197 ScopedColorMask::ScopedColorMask(char red, char green, char blue, char alpha) {
198 glGetBooleanv(GL_COLOR_WRITEMASK, colors_);
199 glColorMask(red, green, blue, alpha);
200 }
201
~ScopedColorMask()202 ScopedColorMask::~ScopedColorMask() {
203 glColorMask(colors_[0], colors_[1], colors_[2], colors_[3]);
204 }
205
ScopedCapability(unsigned capability,unsigned char enabled)206 ScopedCapability::ScopedCapability(unsigned capability, unsigned char enabled)
207 : capability_(capability) {
208 enabled_ = glIsEnabled(capability_);
209 if (enabled == GL_TRUE) {
210 glEnable(capability);
211 } else {
212 glDisable(capability);
213 }
214 }
215
~ScopedCapability()216 ScopedCapability::~ScopedCapability() {
217 if (enabled_ == GL_TRUE) {
218 glEnable(capability_);
219 } else {
220 glDisable(capability_);
221 }
222 }
223
224 } // namespace gl
225