Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_srgb_converter.cc

Issue 2286593002: [Command Buffer] emulate SRGB color format for BlitFramebuffer in OpenGL (Closed)
Patch Set: addressed piman's feedback: use a trivial fragment shader, don't need to explicitly convert linear … Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_srgb_converter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016 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 "gpu/command_buffer/service/gles2_cmd_srgb_converter.h"
6
7 #include "gpu/command_buffer/service/texture_manager.h"
8 #include "ui/gl/gl_version_info.h"
9
10 namespace {
11
12 void CompileShader(GLuint shader, const char* shader_source) {
13 glShaderSource(shader, 1, &shader_source, 0);
14 glCompileShader(shader);
15 #ifndef NDEBUG
16 GLint compile_status;
17 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
18 if (GL_TRUE != compile_status)
19 DLOG(ERROR) << "CopyTexImage: shader compilation failure.";
20 #endif
21 }
22
23 } // anonymous namespace
24
25 namespace gpu {
26 namespace gles2 {
27
28 SRGBConverter::SRGBConverter(
29 const gles2::FeatureInfo* feature_info)
30 : feature_info_(feature_info) {
31 }
32
33 SRGBConverter::~SRGBConverter() {}
34
35
36
37 void SRGBConverter::InitializeSRGBConverterProgram() {
38 if (srgb_converter_program_) {
39 return;
40 }
41
42 srgb_converter_program_ = glCreateProgram();
43
44 // Compile the vertex shader
45 const char* vs_source =
46 "#version 150\n"
47 "out vec2 v_texcoord;\n"
48 "\n"
49 "void main()\n"
50 "{\n"
51 " const vec2 quad_positions[6] = vec2[6]\n"
52 " (\n"
53 " vec2(0.0f, 0.0f),\n"
54 " vec2(0.0f, 1.0f),\n"
55 " vec2(1.0f, 0.0f),\n"
56 "\n"
57 " vec2(0.0f, 1.0f),\n"
58 " vec2(1.0f, 0.0f),\n"
59 " vec2(1.0f, 1.0f)\n"
60 " );\n"
61 "\n"
62 " vec2 xy = vec2((quad_positions[gl_VertexID] * 2.0) - 1.0);\n"
63 " gl_Position = vec4(xy, 0.0, 1.0);\n"
64 " v_texcoord = quad_positions[gl_VertexID];\n"
65 "}\n";
66 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
67 CompileShader(vs, vs_source);
68 glAttachShader(srgb_converter_program_, vs);
69 glDeleteShader(vs);
70
71 // Compile the fragment shader
72
73 // Sampling texels from a srgb texture to a linear image, it will convert
74 // the srgb color space to linear color space automatically as a part of
75 // filtering. See the section <sRGB Texture Color Conversion> in GLES and
76 // OpenGL spec. So in decoder, we don't need to decode again.
77 // Drawing to a srgb image, it will convert linear to srgb automatically.
78 // See the section <sRGB Conversion> in GLES and OpenGL spec.
79 // So we just use a simple fragment shader. We don't need to use an equation
80 // in shader to do explicit srgb conversion to/from linear.
81 const char* fs_source =
82 "#version 150\n"
83 "uniform sampler2D u_source_texture;\n"
84 "in vec2 v_texcoord;\n"
85 "out vec4 output_color;\n"
86 "\n"
87 "void main()\n"
88 "{\n"
89 " vec4 c = texture(u_source_texture, v_texcoord);\n"
90 " output_color = c;\n"
91 "}\n";
92
93 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
94 CompileShader(fs, fs_source);
95 glAttachShader(srgb_converter_program_, fs);
96 glDeleteShader(fs);
97
98 glLinkProgram(srgb_converter_program_);
99 #ifndef NDEBUG
100 GLint linked = 0;
101 glGetProgramiv(srgb_converter_program_, GL_LINK_STATUS, &linked);
102 if (!linked) {
103 DLOG(ERROR) << "BlitFramebuffer: program link failure.";
104 }
105 #endif
106
107 GLuint texture_uniform =
108 glGetUniformLocation(srgb_converter_program_, "u_source_texture");
109 glUseProgram(srgb_converter_program_);
110 glUniform1i(texture_uniform, 0);
111 }
112
113 void SRGBConverter::InitializeSRGBDecoder(
114 const gles2::GLES2Decoder* decoder) {
115 if (srgb_decoder_initialized_) {
116 return;
117 }
118
119 InitializeSRGBConverterProgram();
120
121 glGenTextures(srgb_decoder_textures_.size(), srgb_decoder_textures_.data());
122 glActiveTexture(GL_TEXTURE0);
123 for (auto srgb_decoder_texture : srgb_decoder_textures_) {
124 glBindTexture(GL_TEXTURE_2D, srgb_decoder_texture);
125
126 // Use linear, non-mipmapped sampling with the srgb decoder texture
127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
131 }
132
133 glGenFramebuffersEXT(1, &srgb_decoder_fbo_);
134 glGenVertexArraysOES(1, &srgb_decoder_vao_);
135
136 decoder->RestoreTextureUnitBindings(0);
137 decoder->RestoreActiveTexture();
138 decoder->RestoreProgramBindings();
139
140 srgb_decoder_initialized_ = true;
141 }
142
143 void SRGBConverter::InitializeSRGBEncoder(
144 const gles2::GLES2Decoder* decoder) {
145 if (srgb_encoder_initialized_) {
146 return;
147 }
148
149 InitializeSRGBConverterProgram();
150
151 glGenTextures(srgb_encoder_textures_.size(), srgb_encoder_textures_.data());
152 glActiveTexture(GL_TEXTURE0);
153 for (auto srgb_encoder_texture : srgb_encoder_textures_) {
154 glBindTexture(GL_TEXTURE_2D, srgb_encoder_texture);
155
156 // Use linear, non-mipmapped sampling with the srgb encoder texture
157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
161 }
162
163 glGenFramebuffersEXT(1, &srgb_encoder_fbo_);
164 glGenVertexArraysOES(1, &srgb_encoder_vao_);
165
166 decoder->RestoreTextureUnitBindings(0);
167 decoder->RestoreActiveTexture();
168 decoder->RestoreProgramBindings();
169
170 srgb_encoder_initialized_ = true;
171 }
172
173 void SRGBConverter::Destroy() {
174 if (srgb_decoder_initialized_) {
175 glDeleteTextures(srgb_decoder_textures_.size(),
176 srgb_decoder_textures_.data());
177 srgb_decoder_textures_.fill(0);
178
179 glDeleteFramebuffersEXT(1, &srgb_decoder_fbo_);
180 srgb_decoder_fbo_ = 0;
181
182 glDeleteVertexArraysOES(1, &srgb_decoder_vao_);
183 srgb_decoder_vao_ = 0;
184
185 srgb_decoder_initialized_ = false;
186 }
187
188 if (srgb_encoder_initialized_) {
189 glDeleteTextures(srgb_encoder_textures_.size(),
190 srgb_encoder_textures_.data());
191 srgb_encoder_textures_.fill(0);
192
193 glDeleteFramebuffersEXT(1, &srgb_encoder_fbo_);
194 srgb_encoder_fbo_ = 0;
195
196 glDeleteVertexArraysOES(1, &srgb_encoder_vao_);
197 srgb_encoder_vao_ = 0;
198
199 srgb_encoder_initialized_ = false;
200 }
201
202 glDeleteProgram(srgb_converter_program_);
203 srgb_converter_program_ = 0;
204 }
205
206 void SRGBConverter::SRGBToLinear(
207 const gles2::GLES2Decoder* decoder,
208 GLint srcX0,
209 GLint srcY0,
210 GLint srcX1,
211 GLint srcY1,
212 GLint dstX0,
213 GLint dstY0,
214 GLint dstX1,
215 GLint dstY1,
216 GLbitfield mask,
217 GLenum filter,
218 const gfx::Size& framebuffer_size,
219 GLuint src_framebuffer,
220 GLenum src_framebuffer_internal_format,
221 GLuint dst_framebuffer) {
222 // This function blits srgb image in src fb to linear image in dst fb.
223 // The steps are:
224 // 1) Copy and crop pixels from source srgb image to the 1st texture(srgb).
225 // 2) Sampling from the 1st texture and drawing to the 2nd texture(linear).
226 // During this step, color space is converted from srgb to linear.
227 // 3) Finally, blit pixels from the 2nd texture to the target, which is
228 // also a linear image.
229 DCHECK(srgb_decoder_initialized_);
230
231 // Copy the image from read buffer to the decoder's 1st texture(srgb).
232 // TODO(yunchao) If the read buffer is a fbo texture, we can sample
233 // directly from that texture. In this way, we can save gpu memory.
234 glBindFramebufferEXT(GL_FRAMEBUFFER, src_framebuffer);
235 glActiveTexture(GL_TEXTURE0);
236 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]);
237
238 // We should not copy pixels outside of the read framebuffer. If we read
239 // these pixels, they would become in-bound during BlitFramebuffer. However,
240 // Out-of-bounds pixels will be initialized to 0 in CopyTexSubImage. But they
241 // should read as if the GL_CLAMP_TO_EDGE texture mapping mode were applied
242 // during BlitFramebuffer when the filter is GL_LINEAR.
243 GLuint x = srcX1 > srcX0 ? srcX0 : srcX1;
244 GLuint y = srcY1 > srcY0 ? srcY0 : srcY1;
245 GLuint width = srcX1 > srcX0 ? srcX1 - srcX0 : srcX0 - srcX1;
246 GLuint height = srcY1 > srcY0 ? srcY1 - srcY0 : srcY0 - srcY1;
247 gfx::Rect c(0, 0, framebuffer_size.width(), framebuffer_size.height());
248 c.Intersect(gfx::Rect(x, y, width, height));
249 GLuint xoffset = c.x() - x;
250 GLuint yoffset = c.y() - y;
251 glCopyTexImage2D(GL_TEXTURE_2D, 0, src_framebuffer_internal_format,
yunchao 2016/09/14 16:11:33 If the read buffer is a multisampled renderbuffer
piman 2016/09/15 03:34:31 I'm pretty sure that's the intended behavior - it
yunchao 2016/09/16 06:20:52 Done.
252 c.x(), c.y(), c.width(), c.height(), 0);
253
254 // Make a temporary linear texture as the decoder's 2nd texture, where we
255 // render the converted (srgb to linear) result to.
256 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
257
258 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[1]);
259 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
260 c.width(), c.height(),
261 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
262 glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_decoder_fbo_);
263 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
264 GL_TEXTURE_2D, srgb_decoder_textures_[1], 0);
265
266 // Sampling from the decoder's first texture(srgb) and drawing to the
267 // decoder's 2nd texture(linear),
268 glUseProgram(srgb_converter_program_);
269 glViewport(0, 0, width, height);
270 glDisable(GL_SCISSOR_TEST);
271 glDisable(GL_DEPTH_TEST);
272 glDisable(GL_STENCIL_TEST);
273 glDisable(GL_CULL_FACE);
274 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
275 glDepthMask(GL_FALSE);
276 glDisable(GL_BLEND);
277 glDisable(GL_DITHER);
278
279 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]);
280 glBindVertexArrayOES(srgb_decoder_vao_);
281
282 glDrawArrays(GL_TRIANGLES, 0, 6);
283
284 // Finally, bind the decoder framebuffer as read framebuffer,
285 // blit the converted texture in decoder fbo to the destination texture
286 // in destination framebuffer.
287 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_);
288 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, dst_framebuffer);
289 // Note that the source region has been changed in decoder framebuffer.
290 // The xoffset/yoffset can make bliting clamp to the correct edge if
291 // CLAMP_TO_EDGE is necessary.
292 glBlitFramebuffer(srcX0 < srcX1 ? 0 - xoffset : width - xoffset,
293 srcY0 < srcY1 ? 0 - yoffset : height - yoffset,
294 srcX0 < srcX1 ? width - xoffset : 0 - xoffset,
295 srcY0 < srcY1 ? height - yoffset : 0 - yoffset,
296 dstX0, dstY0, dstX1, dstY1, mask, filter);
297
298 // Restore state
299 decoder->RestoreAllAttributes();
300 decoder->RestoreTextureUnitBindings(0);
301 decoder->RestoreActiveTexture();
302 decoder->RestoreProgramBindings();
303 decoder->RestoreBufferBindings();
304 decoder->RestoreFramebufferBindings();
305 decoder->RestoreGlobalState();
306 }
307
308 void SRGBConverter::LinearToSRGB(
309 const gles2::GLES2Decoder* decoder,
310 GLint srcX0,
311 GLint srcY0,
312 GLint srcX1,
313 GLint srcY1,
314 GLint dstX0,
315 GLint dstY0,
316 GLint dstX1,
317 GLint dstY1,
318 GLbitfield mask,
319 GLenum filter,
320 GLuint src_framebuffer,
321 GLenum src_framebuffer_internal_format,
322 GLenum src_framebuffer_format,
323 GLenum src_framebuffer_type,
324 GLuint dst_framebuffer) {
325 // This function blits linear image in src fb to srgb image in dst fb.
326 // The steps are:
327 // 1) BlitFramebuffer from source linear image to a temp linear texture.
328 // 2) Sampling from the temp texture and drawing to the target srgb
329 // image. During this step, color space is converted from linear to srgb.
330
331 DCHECK(srgb_encoder_initialized_);
332
333 // Create a temp linear texture as draw buffer. Blit framebuffer from
334 // source linear image to the temp linear texture. Filtering is done
335 // during bliting. Note that the src and dst coordinates may be reversed.
336 glActiveTexture(GL_TEXTURE0);
337 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]);
338
339 GLuint width = dstX1 > dstX0 ? dstX1 - dstX0 : dstX0 - dstX1;
340 GLuint height = dstY1 > dstY0 ? dstY1 - dstY0 : dstY0 - dstY1;
341 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
342 glTexImage2D(GL_TEXTURE_2D, 0, src_framebuffer_internal_format,
343 width, height,
344 0, src_framebuffer_format, src_framebuffer_type, nullptr);
345
346 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_encoder_fbo_);
347 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
348 GL_TEXTURE_2D, srgb_encoder_textures_[0], 0);
349 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, src_framebuffer);
350 glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
351 dstX0 < dstX1 ? 0 : width,
352 dstY0 < dstY1 ? 0 : height,
353 dstX0 < dstX1 ? width : 0,
354 dstY0 < dstY1 ? height : 0,
355 mask, filter);
356
357 // Sampling from the linear texture and drawing to the target srgb image.
358 // During this step, color space is converted from linear to srgb. We should
359 // set appropriate viewport to draw to the correct location in target FB.
360 GLuint xstart = dstX0 < dstX1 ? dstX0 : dstX1;
361 GLuint ystart = dstY0 < dstY1 ? dstY0 : dstY1;
362 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, dst_framebuffer);
363 glUseProgram(srgb_converter_program_);
364 glViewport(xstart, ystart, width, height);
365 glDisable(GL_SCISSOR_TEST);
366 glDisable(GL_DEPTH_TEST);
367 glDisable(GL_STENCIL_TEST);
368 glDisable(GL_CULL_FACE);
369 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
370 glDepthMask(GL_FALSE);
371 glDisable(GL_BLEND);
372 glDisable(GL_DITHER);
373
374 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]);
375 glBindVertexArrayOES(srgb_encoder_vao_);
376
377 glDrawArrays(GL_TRIANGLES, 0, 6);
378
379 // Restore state
380 decoder->RestoreAllAttributes();
381 decoder->RestoreTextureUnitBindings(0);
382 decoder->RestoreActiveTexture();
383 decoder->RestoreProgramBindings();
384 decoder->RestoreBufferBindings();
385 decoder->RestoreFramebufferBindings();
386 decoder->RestoreGlobalState();
387 }
388
389 void SRGBConverter::SRGBToSRGB(
390 const gles2::GLES2Decoder* decoder,
391 GLint srcX0,
392 GLint srcY0,
393 GLint srcX1,
394 GLint srcY1,
395 GLint dstX0,
396 GLint dstY0,
397 GLint dstX1,
398 GLint dstY1,
399 GLbitfield mask,
400 GLenum filter,
401 const gfx::Size& framebuffer_size,
402 GLuint src_framebuffer,
403 GLenum src_framebuffer_internal_format,
404 GLuint dst_framebuffer) {
405 // This function blits srgb image in src fb to srgb image in dst fb.
406 // It needs to use decoder's resource, as well as encoder's resources,
407 // for instance, decoder's and encoder's fbos, programs and textuers.
408 // The steps are:
409 // 1) Copy and crop pixels from source srgb image to the 1st texture(srgb).
410 // 2) Sampling from the 1st texture and drawing to the 2nd texture(linear).
411 // During this step, color space is converted from srgb to linear.
412 // 3) Blit pixels from the 2nd texture to the 3rd texture(linear).
413 // 4) Sampling from the 3rd texture and drawing to the dst image(srgb).
414 // During this step, color space is converted from linear to srgb.
piman 2016/09/15 03:34:31 The 2 other functions could be considered a simpli
yunchao 2016/09/16 06:20:52 Done. Very good idea to remove the code duplicatio
yunchao 2016/09/16 14:07:56 It is not necessary to associate texture and vao w
415 DCHECK(srgb_decoder_initialized_ && srgb_encoder_initialized_);
416
417 // Copy the image from read buffer to the decoder's 1st texture(srgb).
418 // TODO(yunchao) If the read buffer is a fbo texture, we can sample
419 // directly from that texture. In this way, we can save gpu memory.
420 glBindFramebufferEXT(GL_FRAMEBUFFER, src_framebuffer);
421 glActiveTexture(GL_TEXTURE0);
422 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]);
423
424 // We should not copy pixels outside of the read framebuffer. If we read
425 // these pixels, they would become in-bound during BlitFramebuffer. However,
426 // Out-of-bounds pixels will be initialized to 0 in CopyTexSubImage. But they
427 // should read as if the GL_CLAMP_TO_EDGE texture mapping mode were applied
428 // during BlitFramebuffer when the filter is GL_LINEAR.
429 GLuint x = srcX1 > srcX0 ? srcX0 : srcX1;
430 GLuint y = srcY1 > srcY0 ? srcY0 : srcY1;
431 GLuint width_read = srcX1 > srcX0 ? srcX1 - srcX0 : srcX0 - srcX1;
432 GLuint height_read = srcY1 > srcY0 ? srcY1 - srcY0 : srcY0 - srcY1;
433 gfx::Rect c(0, 0, framebuffer_size.width(), framebuffer_size.height());
434 c.Intersect(gfx::Rect(x, y, width_read, height_read));
435 GLuint xoffset = c.x() - x;
436 GLuint yoffset = c.y() - y;
437 glCopyTexImage2D(GL_TEXTURE_2D, 0, src_framebuffer_internal_format,
438 c.x(), c.y(), c.width(), c.height(), 0);
439
440 // Make a temporary linear texture as the decoder's 2nd texture, where we
441 // render the converted (srgb to linear) result to.
442 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
443
444 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[1]);
445 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
446 c.width(), c.height(),
447 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
448 glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_decoder_fbo_);
449 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
450 GL_TEXTURE_2D, srgb_decoder_textures_[1], 0);
451
452 // Sampling from the decoder's first texture(srgb) and drawing to the
453 // decoder's 2nd texture(linear),
454 glUseProgram(srgb_converter_program_);
455 glViewport(0, 0, width_read, height_read);
456 glDisable(GL_SCISSOR_TEST);
457 glDisable(GL_DEPTH_TEST);
458 glDisable(GL_STENCIL_TEST);
459 glDisable(GL_CULL_FACE);
460 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
461 glDepthMask(GL_FALSE);
462 glDisable(GL_BLEND);
463 glDisable(GL_DITHER);
464
465 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]);
466 glBindVertexArrayOES(srgb_decoder_vao_);
467
468 glDrawArrays(GL_TRIANGLES, 0, 6);
469
470 // Create the 3rd texture(linear) as encoder's draw buffer. Blit framebuffer
471 // from the 2nd texture(linear) to the 3rd texture. Filtering is done
472 // during bliting. Note that the src and dst coordinates may be reversed.
473 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]);
474
475 GLuint width_draw = dstX1 > dstX0 ? dstX1 - dstX0 : dstX0 - dstX1;
476 GLuint height_draw = dstY1 > dstY0 ? dstY1 - dstY0 : dstY0 - dstY1;
477 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
478 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
479 width_draw, height_draw,
480 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
481
482 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_encoder_fbo_);
483 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
484 GL_TEXTURE_2D, srgb_encoder_textures_[0], 0);
485 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_);
486 glBlitFramebuffer(srcX0 < srcX1 ? 0 - xoffset : width_read - xoffset,
487 srcY0 < srcY1 ? 0 - yoffset : height_read - yoffset,
488 srcX0 < srcX1 ? width_read - xoffset : 0 - xoffset,
489 srcY0 < srcY1 ? height_read - yoffset : 0 - yoffset,
490 dstX0 < dstX1 ? 0 : width_draw,
491 dstY0 < dstY1 ? 0 : height_draw,
492 dstX0 < dstX1 ? width_draw : 0,
493 dstY0 < dstY1 ? height_draw : 0,
494 mask, filter);
495
496 // Sampling from the 3rd texture(linear) and drawing to the target srgb image.
497 // During this step, color space is converted from linear to srgb. We should
498 // set appropriate viewport to draw to the correct location in target FB.
499 GLuint xstart = dstX0 < dstX1 ? dstX0 : dstX1;
500 GLuint ystart = dstY0 < dstY1 ? dstY0 : dstY1;
501 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, dst_framebuffer);
502 glUseProgram(srgb_converter_program_);
503 glViewport(xstart, ystart, width_draw, height_draw);
504
505 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]);
506 glBindVertexArrayOES(srgb_encoder_vao_);
507
508 glDrawArrays(GL_TRIANGLES, 0, 6);
509
510 // Restore state
511 decoder->RestoreAllAttributes();
512 decoder->RestoreTextureUnitBindings(0);
513 decoder->RestoreActiveTexture();
514 decoder->RestoreProgramBindings();
515 decoder->RestoreBufferBindings();
516 decoder->RestoreFramebufferBindings();
517 decoder->RestoreGlobalState();
518 }
519
520 } // namespace gles2.
521 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_srgb_converter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698