OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
10 #include "gpu/command_buffer/service/gl_utils.h" | 11 #include "gpu/command_buffer/service/gl_utils.h" |
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
13 #include "gpu/command_buffer/service/texture_manager.h" | |
12 | 14 |
13 #define SHADER(src) \ | 15 #define SHADER(src) \ |
14 "#ifdef GL_ES\n" \ | 16 "#ifdef GL_ES\n" \ |
15 "precision mediump float;\n" \ | 17 "precision mediump float;\n" \ |
16 "#define TexCoordPrecision mediump\n" \ | 18 "#define TexCoordPrecision mediump\n" \ |
17 "#else\n" \ | 19 "#else\n" \ |
18 "#define TexCoordPrecision\n" \ | 20 "#define TexCoordPrecision\n" \ |
19 "#endif\n" #src | 21 "#endif\n" #src |
20 #define SHADER_2D(src) \ | 22 #define SHADER_2D(src) \ |
21 "#define SamplerType sampler2D\n" \ | 23 "#define SamplerType sampler2D\n" \ |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 } | 195 } |
194 | 196 |
195 void DeleteShader(GLuint shader) { | 197 void DeleteShader(GLuint shader) { |
196 if (shader) | 198 if (shader) |
197 glDeleteShader(shader); | 199 glDeleteShader(shader); |
198 } | 200 } |
199 | 201 |
200 bool BindFramebufferTexture2D(GLenum target, | 202 bool BindFramebufferTexture2D(GLenum target, |
201 GLuint texture_id, | 203 GLuint texture_id, |
202 GLuint framebuffer) { | 204 GLuint framebuffer) { |
203 DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB); | 205 GLenum binding_target = |
206 gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(target); | |
207 DCHECK(binding_target == GL_TEXTURE_2D || | |
208 binding_target == GL_TEXTURE_RECTANGLE_ARB || | |
209 binding_target == GL_TEXTURE_CUBE_MAP); | |
204 glActiveTexture(GL_TEXTURE0); | 210 glActiveTexture(GL_TEXTURE0); |
205 glBindTexture(target, texture_id); | 211 glBindTexture(binding_target, texture_id); |
206 // NVidia drivers require texture settings to be a certain way | 212 // NVidia drivers require texture settings to be a certain way |
207 // or they won't report FRAMEBUFFER_COMPLETE. | 213 // or they won't report FRAMEBUFFER_COMPLETE. |
208 glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 214 glTexParameterf(binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
209 glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 215 glTexParameterf(binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
210 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 216 glTexParameteri(binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
211 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 217 glTexParameteri(binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
212 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); | 218 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); |
213 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | 219 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, |
214 texture_id, 0); | 220 texture_id, 0); |
215 | 221 |
216 #ifndef NDEBUG | 222 #ifndef NDEBUG |
217 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 223 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
218 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 224 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
219 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 225 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
220 return false; | 226 return false; |
221 } | 227 } |
222 #endif | 228 #endif |
223 return true; | 229 return true; |
224 } | 230 } |
225 | 231 |
226 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, | 232 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, |
227 GLenum source_target, | 233 GLenum source_target, |
228 GLuint source_id, | 234 GLuint source_id, |
235 GLenum dest_target, | |
229 GLuint dest_id, | 236 GLuint dest_id, |
230 GLenum dest_internal_format, | 237 GLenum dest_internal_format, |
231 GLsizei width, | 238 GLsizei width, |
232 GLsizei height, | 239 GLsizei height, |
233 GLuint framebuffer) { | 240 GLuint framebuffer) { |
234 DCHECK(source_target == GL_TEXTURE_2D || | 241 DCHECK(source_target == GL_TEXTURE_2D || |
235 source_target == GL_TEXTURE_RECTANGLE_ARB); | 242 source_target == GL_TEXTURE_RECTANGLE_ARB); |
236 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { | 243 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { |
237 glBindTexture(GL_TEXTURE_2D, dest_id); | 244 GLenum binding_target = |
238 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 245 gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target); |
239 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 246 glBindTexture(binding_target, dest_id); |
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 247 glTexParameterf(binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 248 glTexParameterf(binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
242 glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format, | 249 glTexParameteri(binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
250 glTexParameteri(binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
251 glCopyTexImage2D(dest_target, 0 /* level */, dest_internal_format, | |
243 0 /* x */, 0 /* y */, width, height, 0 /* border */); | 252 0 /* x */, 0 /* y */, width, height, 0 /* border */); |
244 } | 253 } |
245 | 254 |
246 decoder->RestoreTextureState(source_id); | 255 decoder->RestoreTextureState(source_id); |
247 decoder->RestoreTextureState(dest_id); | 256 decoder->RestoreTextureState(dest_id); |
248 decoder->RestoreTextureUnitBindings(0); | 257 decoder->RestoreTextureUnitBindings(0); |
249 decoder->RestoreActiveTexture(); | 258 decoder->RestoreActiveTexture(); |
250 decoder->RestoreFramebufferBindings(); | 259 decoder->RestoreFramebufferBindings(); |
251 } | 260 } |
252 | 261 |
253 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, | 262 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, |
254 GLenum source_target, | 263 GLenum source_target, |
255 GLuint source_id, | 264 GLuint source_id, |
265 GLenum dest_target, | |
256 GLuint dest_id, | 266 GLuint dest_id, |
257 GLint xoffset, | 267 GLint xoffset, |
258 GLint yoffset, | 268 GLint yoffset, |
259 GLint source_x, | 269 GLint source_x, |
260 GLint source_y, | 270 GLint source_y, |
261 GLsizei source_width, | 271 GLsizei source_width, |
262 GLsizei source_height, | 272 GLsizei source_height, |
263 GLuint framebuffer) { | 273 GLuint framebuffer) { |
264 DCHECK(source_target == GL_TEXTURE_2D || | 274 DCHECK(source_target == GL_TEXTURE_2D || |
265 source_target == GL_TEXTURE_RECTANGLE_ARB); | 275 source_target == GL_TEXTURE_RECTANGLE_ARB); |
266 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { | 276 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { |
267 glBindTexture(GL_TEXTURE_2D, dest_id); | 277 GLenum binding_target = |
268 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 278 gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target); |
269 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 279 glBindTexture(binding_target, dest_id); |
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 280 glTexParameterf(binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 281 glTexParameterf(binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
272 glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset, | 282 glTexParameteri(binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
273 source_x, source_y, source_width, source_height); | 283 glTexParameteri(binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
284 glCopyTexSubImage2D(dest_target, 0 /* level */, xoffset, yoffset, source_x, | |
285 source_y, source_width, source_height); | |
274 } | 286 } |
275 | 287 |
276 decoder->RestoreTextureState(source_id); | 288 decoder->RestoreTextureState(source_id); |
277 decoder->RestoreTextureState(dest_id); | 289 decoder->RestoreTextureState(dest_id); |
278 decoder->RestoreTextureUnitBindings(0); | 290 decoder->RestoreTextureUnitBindings(0); |
279 decoder->RestoreActiveTexture(); | 291 decoder->RestoreActiveTexture(); |
280 decoder->RestoreFramebufferBindings(); | 292 decoder->RestoreFramebufferBindings(); |
281 } | 293 } |
282 | 294 |
295 class ScopedStagingTexture { | |
296 public: | |
297 ScopedStagingTexture() { | |
298 glGenTextures(1, &staging_texture_); | |
299 glBindTexture(GL_TEXTURE_2D, staging_texture_); | |
300 } | |
301 ~ScopedStagingTexture() { | |
302 glDeleteTextures(1, &staging_texture_); | |
303 staging_texture_ = 0; | |
304 } | |
305 | |
306 GLuint texture() const { return staging_texture_; } | |
307 | |
308 private: | |
309 GLuint staging_texture_; | |
310 }; | |
311 | |
312 bool NeedOneCopy(GLenum target, | |
313 const gpu::gles2::DecoderTextureState* texture_state) { | |
314 GLenum binding_target = | |
315 gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(target); | |
316 | |
317 if (binding_target != GL_TEXTURE_CUBE_MAP) | |
318 return false; | |
319 DCHECK(texture_state); | |
320 | |
321 // The drivers with |force_cube_complete| or | |
322 // |force_cube_map_positive_x_allocation| don't guarantee that the FBO binding | |
323 // cube map texture works. | |
324 return texture_state->force_cube_complete || | |
325 texture_state->force_cube_map_positive_x_allocation; | |
dshwang
2015/09/02 11:01:19
We don't ensure if it's fine for FBO to bind cube
piman
2015/09/03 19:13:26
Could you file a bug to describe the issue (if the
dshwang
2015/09/04 06:23:13
Yes, I filed https://code.google.com/p/chromium/is
| |
326 } | |
327 | |
283 } // namespace | 328 } // namespace |
284 | 329 |
285 namespace gpu { | 330 namespace gpu { |
286 | 331 |
287 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 332 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
288 : initialized_(false), | 333 : initialized_(false), |
289 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), | 334 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), |
290 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), | 335 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), |
291 buffer_id_(0u), | 336 buffer_id_(0u), |
292 framebuffer_(0u) {} | 337 framebuffer_(0u) {} |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 | 387 |
343 glDeleteBuffersARB(1, &buffer_id_); | 388 glDeleteBuffersARB(1, &buffer_id_); |
344 buffer_id_ = 0; | 389 buffer_id_ = 0; |
345 } | 390 } |
346 | 391 |
347 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 392 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
348 const gles2::GLES2Decoder* decoder, | 393 const gles2::GLES2Decoder* decoder, |
349 GLenum source_target, | 394 GLenum source_target, |
350 GLuint source_id, | 395 GLuint source_id, |
351 GLenum source_internal_format, | 396 GLenum source_internal_format, |
397 GLenum dest_target, | |
352 GLuint dest_id, | 398 GLuint dest_id, |
353 GLenum dest_internal_format, | 399 GLenum dest_internal_format, |
400 GLenum dest_type, | |
354 GLsizei width, | 401 GLsizei width, |
355 GLsizei height, | 402 GLsizei height, |
356 bool flip_y, | 403 bool flip_y, |
357 bool premultiply_alpha, | 404 bool premultiply_alpha, |
358 bool unpremultiply_alpha) { | 405 bool unpremultiply_alpha, |
406 const gles2::DecoderTextureState* texture_state) { | |
359 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 407 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
360 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 408 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's |
361 // format does not contain a superset of the components required by the base | 409 // format does not contain a superset of the components required by the base |
362 // format of internalformat. | 410 // format of internalformat. |
363 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | 411 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml |
364 bool source_format_contain_superset_of_dest_format = | 412 bool source_format_contain_superset_of_dest_format = |
365 (source_internal_format == dest_internal_format && | 413 (source_internal_format == dest_internal_format && |
366 source_internal_format != GL_BGRA_EXT) || | 414 source_internal_format != GL_BGRA_EXT) || |
367 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | 415 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); |
368 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 416 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
369 // so restrict this to GL_TEXTURE_2D. | 417 // so restrict this to GL_TEXTURE_2D. |
370 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | 418 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
371 source_format_contain_superset_of_dest_format) { | 419 source_format_contain_superset_of_dest_format) { |
372 DoCopyTexImage2D(decoder, | 420 DoCopyTexImage2D(decoder, source_target, source_id, dest_target, dest_id, |
373 source_target, | 421 dest_internal_format, width, height, framebuffer_); |
374 source_id, | |
375 dest_id, | |
376 dest_internal_format, | |
377 width, | |
378 height, | |
379 framebuffer_); | |
380 return; | 422 return; |
381 } | 423 } |
382 | 424 |
383 // Use kIdentityMatrix if no transform passed in. | 425 // Use kIdentityMatrix if no transform passed in. |
384 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width, | 426 DoCopyTextureWithTransform( |
385 height, flip_y, premultiply_alpha, | 427 decoder, source_target, source_id, dest_target, dest_id, |
386 unpremultiply_alpha, kIdentityMatrix); | 428 dest_internal_format, dest_type, width, height, flip_y, premultiply_alpha, |
429 unpremultiply_alpha, texture_state, kIdentityMatrix); | |
387 } | 430 } |
388 | 431 |
389 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( | 432 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
390 const gles2::GLES2Decoder* decoder, | 433 const gles2::GLES2Decoder* decoder, |
391 GLenum source_target, | 434 GLenum source_target, |
392 GLuint source_id, | 435 GLuint source_id, |
393 GLenum source_internal_format, | 436 GLenum source_internal_format, |
437 GLenum dest_target, | |
394 GLuint dest_id, | 438 GLuint dest_id, |
395 GLenum dest_internal_format, | 439 GLenum dest_internal_format, |
440 GLenum dest_type, | |
396 GLint xoffset, | 441 GLint xoffset, |
397 GLint yoffset, | 442 GLint yoffset, |
398 GLint x, | 443 GLint x, |
399 GLint y, | 444 GLint y, |
400 GLsizei width, | 445 GLsizei width, |
401 GLsizei height, | 446 GLsizei height, |
402 GLsizei dest_width, | 447 GLsizei dest_width, |
403 GLsizei dest_height, | 448 GLsizei dest_height, |
404 GLsizei source_width, | 449 GLsizei source_width, |
405 GLsizei source_height, | 450 GLsizei source_height, |
406 bool flip_y, | 451 bool flip_y, |
407 bool premultiply_alpha, | 452 bool premultiply_alpha, |
408 bool unpremultiply_alpha) { | 453 bool unpremultiply_alpha, |
454 const gles2::DecoderTextureState* texture_state) { | |
409 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 455 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
410 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 456 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's |
411 // format does not contain a superset of the components required by the base | 457 // format does not contain a superset of the components required by the base |
412 // format of internalformat. | 458 // format of internalformat. |
413 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | 459 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml |
414 bool source_format_contain_superset_of_dest_format = | 460 bool source_format_contain_superset_of_dest_format = |
415 (source_internal_format == dest_internal_format && | 461 (source_internal_format == dest_internal_format && |
416 source_internal_format != GL_BGRA_EXT) || | 462 source_internal_format != GL_BGRA_EXT) || |
417 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | 463 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); |
418 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 464 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
419 // so restrict this to GL_TEXTURE_2D. | 465 // so restrict this to GL_TEXTURE_2D. |
420 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | 466 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
421 source_format_contain_superset_of_dest_format) { | 467 source_format_contain_superset_of_dest_format) { |
422 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset, | 468 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, |
423 yoffset, x, y, width, height, framebuffer_); | 469 xoffset, yoffset, x, y, width, height, framebuffer_); |
424 return; | 470 return; |
425 } | 471 } |
426 | 472 |
427 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset, | 473 if (NeedOneCopy(dest_target, texture_state)) { |
428 yoffset, x, y, width, height, dest_width, dest_height, | 474 ScopedStagingTexture staging_texture; |
dshwang
2015/09/02 11:01:19
as kbr suggested to destruct texture after workaro
| |
429 source_width, source_height, flip_y, premultiply_alpha, | 475 glTexImage2D(GL_TEXTURE_2D, 0, dest_internal_format, width, height, 0, |
430 unpremultiply_alpha, kIdentityMatrix); | 476 dest_internal_format, dest_type, nullptr); |
477 DoCopyTextureInternal(decoder, source_target, source_id, GL_TEXTURE_2D, | |
478 staging_texture.texture(), 0, 0, x, y, width, height, | |
479 width, height, source_width, source_height, flip_y, | |
480 premultiply_alpha, unpremultiply_alpha, | |
481 kIdentityMatrix); | |
482 DoCopyTexSubImage2D(decoder, GL_TEXTURE_2D, staging_texture.texture(), | |
483 dest_target, dest_id, xoffset, yoffset, 0, 0, width, | |
484 height, framebuffer_); | |
485 return; | |
486 } | |
487 | |
488 DoCopyTextureInternal( | |
489 decoder, source_target, source_id, dest_target, dest_id, xoffset, yoffset, | |
490 x, y, width, height, dest_width, dest_height, source_width, source_height, | |
491 flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | |
431 } | 492 } |
432 | 493 |
433 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( | 494 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
434 const gles2::GLES2Decoder* decoder, | 495 const gles2::GLES2Decoder* decoder, |
435 GLenum source_target, | 496 GLenum source_target, |
436 GLuint source_id, | 497 GLuint source_id, |
498 GLenum dest_target, | |
437 GLuint dest_id, | 499 GLuint dest_id, |
500 GLenum dest_internal_format, | |
501 GLenum dest_type, | |
438 GLsizei width, | 502 GLsizei width, |
439 GLsizei height, | 503 GLsizei height, |
440 bool flip_y, | 504 bool flip_y, |
441 bool premultiply_alpha, | 505 bool premultiply_alpha, |
442 bool unpremultiply_alpha, | 506 bool unpremultiply_alpha, |
507 const gles2::DecoderTextureState* texture_state, | |
443 const GLfloat transform_matrix[16]) { | 508 const GLfloat transform_matrix[16]) { |
444 GLsizei dest_width = width; | 509 GLsizei dest_width = width; |
445 GLsizei dest_height = height; | 510 GLsizei dest_height = height; |
446 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0, 0, 0, | 511 |
447 width, height, dest_width, dest_height, width, height, | 512 if (NeedOneCopy(dest_target, texture_state)) { |
448 flip_y, premultiply_alpha, unpremultiply_alpha, | 513 // The |dest_id| texture cannot be bound to FBO. Create a staging |
449 transform_matrix); | 514 // GL_TEXTURE_2D texture, and copy the source texture to the staging |
515 // texture, and copy the staging texture to the dest texture. | |
516 ScopedStagingTexture staging_texture; | |
517 glTexImage2D(GL_TEXTURE_2D, 0, dest_internal_format, width, height, 0, | |
518 dest_internal_format, dest_type, nullptr); | |
519 DoCopyTextureInternal(decoder, source_target, source_id, GL_TEXTURE_2D, | |
520 staging_texture.texture(), 0, 0, 0, 0, width, height, | |
521 width, height, width, height, flip_y, | |
522 premultiply_alpha, unpremultiply_alpha, | |
523 transform_matrix); | |
524 DoCopyTexImage2D(decoder, GL_TEXTURE_2D, staging_texture.texture(), | |
525 dest_target, dest_id, dest_internal_format, width, height, | |
526 framebuffer_); | |
527 return; | |
528 } | |
529 | |
530 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, | |
531 0, 0, 0, 0, width, height, dest_width, dest_height, | |
532 width, height, flip_y, premultiply_alpha, | |
533 unpremultiply_alpha, transform_matrix); | |
450 } | 534 } |
451 | 535 |
452 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( | 536 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( |
453 const gles2::GLES2Decoder* decoder, | 537 const gles2::GLES2Decoder* decoder, |
454 GLenum source_target, | 538 GLenum source_target, |
455 GLuint source_id, | 539 GLuint source_id, |
540 GLenum dest_target, | |
456 GLuint dest_id, | 541 GLuint dest_id, |
457 GLint xoffset, | 542 GLint xoffset, |
458 GLint yoffset, | 543 GLint yoffset, |
459 GLint x, | 544 GLint x, |
460 GLint y, | 545 GLint y, |
461 GLsizei width, | 546 GLsizei width, |
462 GLsizei height, | 547 GLsizei height, |
463 GLsizei dest_width, | 548 GLsizei dest_width, |
464 GLsizei dest_height, | 549 GLsizei dest_height, |
465 GLsizei source_width, | 550 GLsizei source_width, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
537 // Pass translation to the shader program. | 622 // Pass translation to the shader program. |
538 glUniform2f(info->vertex_translate_handle, x_translate_on_vertex, | 623 glUniform2f(info->vertex_translate_handle, x_translate_on_vertex, |
539 y_translate_on_vertex); | 624 y_translate_on_vertex); |
540 } | 625 } |
541 if (source_target == GL_TEXTURE_RECTANGLE_ARB) | 626 if (source_target == GL_TEXTURE_RECTANGLE_ARB) |
542 glUniform2f(info->half_size_handle, source_width / 2.0f, | 627 glUniform2f(info->half_size_handle, source_width / 2.0f, |
543 source_height / 2.0f); | 628 source_height / 2.0f); |
544 else | 629 else |
545 glUniform2f(info->half_size_handle, 0.5f, 0.5f); | 630 glUniform2f(info->half_size_handle, 0.5f, 0.5f); |
546 | 631 |
547 if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) { | 632 if (BindFramebufferTexture2D(dest_target, dest_id, framebuffer_)) { |
548 #ifndef NDEBUG | 633 #ifndef NDEBUG |
549 // glValidateProgram of MACOSX validates FBO unlike other platforms, so | 634 // glValidateProgram of MACOSX validates FBO unlike other platforms, so |
550 // glValidateProgram must be called after FBO binding. crbug.com/463439 | 635 // glValidateProgram must be called after FBO binding. crbug.com/463439 |
551 glValidateProgram(info->program); | 636 glValidateProgram(info->program); |
552 GLint validation_status; | 637 GLint validation_status; |
553 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); | 638 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
554 if (GL_TRUE != validation_status) { | 639 if (GL_TRUE != validation_status) { |
555 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 640 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
556 return; | 641 return; |
557 } | 642 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
594 decoder->RestoreTextureState(dest_id); | 679 decoder->RestoreTextureState(dest_id); |
595 decoder->RestoreTextureUnitBindings(0); | 680 decoder->RestoreTextureUnitBindings(0); |
596 decoder->RestoreActiveTexture(); | 681 decoder->RestoreActiveTexture(); |
597 decoder->RestoreProgramBindings(); | 682 decoder->RestoreProgramBindings(); |
598 decoder->RestoreBufferBindings(); | 683 decoder->RestoreBufferBindings(); |
599 decoder->RestoreFramebufferBindings(); | 684 decoder->RestoreFramebufferBindings(); |
600 decoder->RestoreGlobalState(); | 685 decoder->RestoreGlobalState(); |
601 } | 686 } |
602 | 687 |
603 } // namespace gpu | 688 } // namespace gpu |
OLD | NEW |