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

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

Issue 2623863002: Support level > 0 for CopyTextureCHROMIUM extension (Closed)
Patch Set: Created 3 years, 11 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
OLDNEW
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_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after
2017 const char* function_name, 2017 const char* function_name,
2018 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, 2018 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
2019 GLsizei width, GLsizei height, GLsizei depth, GLenum format, 2019 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
2020 Texture* texture); 2020 Texture* texture);
2021 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name, 2021 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name,
2022 TextureRef* source_texture_ref, 2022 TextureRef* source_texture_ref,
2023 TextureRef* dest_texture_ref); 2023 TextureRef* dest_texture_ref);
2024 CopyTextureMethod ValidateCopyTextureCHROMIUMInternalFormats( 2024 CopyTextureMethod ValidateCopyTextureCHROMIUMInternalFormats(
2025 const char* function_name, 2025 const char* function_name,
2026 TextureRef* source_texture_ref, 2026 TextureRef* source_texture_ref,
2027 GLint source_level,
2027 GLenum dest_internal_format); 2028 GLenum dest_internal_format);
2028 bool ValidateCompressedCopyTextureCHROMIUM(const char* function_name, 2029 bool ValidateCompressedCopyTextureCHROMIUM(const char* function_name,
2029 TextureRef* source_texture_ref, 2030 TextureRef* source_texture_ref,
2030 TextureRef* dest_texture_ref); 2031 TextureRef* dest_texture_ref);
2031 2032
2032 void RenderWarning(const char* filename, int line, const std::string& msg); 2033 void RenderWarning(const char* filename, int line, const std::string& msg);
2033 void PerformanceWarning( 2034 void PerformanceWarning(
2034 const char* filename, int line, const std::string& msg); 2035 const char* filename, int line, const std::string& msg);
2035 2036
2036 const FeatureInfo::FeatureFlags& features() const { 2037 const FeatureInfo::FeatureFlags& features() const {
(...skipping 14149 matching lines...) Expand 10 before | Expand all | Expand 10 after
16186 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, 16187 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
16187 "invalid source texture target binding"); 16188 "invalid source texture target binding");
16188 return false; 16189 return false;
16189 } 16190 }
16190 return true; 16191 return true;
16191 } 16192 }
16192 16193
16193 CopyTextureMethod GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats( 16194 CopyTextureMethod GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats(
16194 const char* function_name, 16195 const char* function_name,
16195 TextureRef* source_texture_ref, 16196 TextureRef* source_texture_ref,
16197 GLint source_level,
16196 GLenum dest_internal_format) { 16198 GLenum dest_internal_format) {
16197 GLenum source_type = 0; 16199 GLenum source_type = 0;
16198 GLenum source_internal_format = 0; 16200 GLenum source_internal_format = 0;
16199 Texture* source_texture = source_texture_ref->texture(); 16201 Texture* source_texture = source_texture_ref->texture();
16200 source_texture->GetLevelType(source_texture->target(), 0, &source_type, 16202 source_texture->GetLevelType(source_texture->target(), source_level,
16201 &source_internal_format); 16203 &source_type, &source_internal_format);
16202 16204
16203 bool valid_dest_format = false; 16205 bool valid_dest_format = false;
16204 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats 16206 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats
16205 // are not supported on GL core profile. See crbug.com/577144. Enable the 16207 // are not supported on GL core profile. See crbug.com/577144. Enable the
16206 // workaround for glCopyTexImage and glCopyTexSubImage in 16208 // workaround for glCopyTexImage and glCopyTexSubImage in
16207 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation. 16209 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation.
16208 switch (dest_internal_format) { 16210 switch (dest_internal_format) {
16209 case GL_RGB: 16211 case GL_RGB:
16210 case GL_RGBA: 16212 case GL_RGBA:
16211 case GL_RGB8: 16213 case GL_RGB8:
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
16355 GLuint dest_id, 16357 GLuint dest_id,
16356 GLint dest_level, 16358 GLint dest_level,
16357 GLenum internal_format, 16359 GLenum internal_format,
16358 GLenum dest_type, 16360 GLenum dest_type,
16359 GLboolean unpack_flip_y, 16361 GLboolean unpack_flip_y,
16360 GLboolean unpack_premultiply_alpha, 16362 GLboolean unpack_premultiply_alpha,
16361 GLboolean unpack_unmultiply_alpha) { 16363 GLboolean unpack_unmultiply_alpha) {
16362 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); 16364 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
16363 static const char kFunctionName[] = "glCopyTextureCHROMIUM"; 16365 static const char kFunctionName[] = "glCopyTextureCHROMIUM";
16364 16366
16365 // TODO(qiankun.miao@intel.com): Remove this after level > 0 support is
16366 // implemented. See: https://crbug.com/612542.
16367 DCHECK(source_level == 0);
16368 DCHECK(dest_level == 0);
16369
16370 TextureRef* source_texture_ref = GetTexture(source_id); 16367 TextureRef* source_texture_ref = GetTexture(source_id);
16371 TextureRef* dest_texture_ref = GetTexture(dest_id); 16368 TextureRef* dest_texture_ref = GetTexture(dest_id);
16372 16369
16373 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref, 16370 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref,
16374 dest_texture_ref)) { 16371 dest_texture_ref)) {
16375 return; 16372 return;
16376 } 16373 }
16377 16374
16375 if (source_level < 0 || dest_level < 0 ||
16376 (feature_info_->IsWebGL1OrES2Context() && source_level > 0)) {
16377 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16378 "source_level or dest_level out of range");
16379 return;
16380 }
16381
16378 Texture* source_texture = source_texture_ref->texture(); 16382 Texture* source_texture = source_texture_ref->texture();
16379 Texture* dest_texture = dest_texture_ref->texture(); 16383 Texture* dest_texture = dest_texture_ref->texture();
16380 GLenum source_target = source_texture->target(); 16384 GLenum source_target = source_texture->target();
16381 GLenum dest_target = dest_texture->target(); 16385 GLenum dest_target = dest_texture->target();
16382 16386
16383 GLenum source_type = 0; 16387 GLenum source_type = 0;
16384 GLenum source_internal_format = 0; 16388 GLenum source_internal_format = 0;
16385 source_texture->GetLevelType(source_target, 0, &source_type, 16389 source_texture->GetLevelType(source_target, source_level, &source_type,
16386 &source_internal_format); 16390 &source_internal_format);
16387 GLenum format = 16391 GLenum format =
16388 TextureManager::ExtractFormatFromStorageFormat(internal_format); 16392 TextureManager::ExtractFormatFromStorageFormat(internal_format);
16389 if (!texture_manager()->ValidateTextureParameters( 16393 if (!texture_manager()->ValidateTextureParameters(
16390 GetErrorState(), kFunctionName, true, format, dest_type, 16394 GetErrorState(), kFunctionName, true, format, dest_type,
16391 internal_format, 0)) { 16395 internal_format, dest_level)) {
16392 return; 16396 return;
16393 } 16397 }
16394 16398
16395 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats( 16399 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats(
16396 kFunctionName, source_texture_ref, internal_format); 16400 kFunctionName, source_texture_ref, source_level, internal_format);
16397 // INVALID_OPERATION is already generated by 16401 // INVALID_OPERATION is already generated by
16398 // ValidateCopyTextureCHROMIUMInternalFormats. 16402 // ValidateCopyTextureCHROMIUMInternalFormats.
16399 if (NOT_COPYABLE == method) { 16403 if (method == NOT_COPYABLE) {
16400 return; 16404 return;
16401 } 16405 }
16402 16406
16407 // Draw to a fbo attaching level 0 of an intermediate texture,
16408 // then copy from the fbo to dest texture level with glCopyTexImage2D.
16409 // For WebGL 1.0 or OpenGL ES 2.0, DIRECT_DRAW path isn't available for
16410 // dest_level > 0 due to level > 0 isn't supported by glFramebufferTexture2D
16411 // in ES2 context. Go to DRAW_AND_COPY path in this case.
16412 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
16413 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
16414 // 0 are not available due to a framebuffer completeness bug:
16415 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and
16416 // OpenGL ES 3.0 can be lifted.
16417 if ((dest_level > 0 && method == DIRECT_DRAW) ||
16418 (source_level > 0 && method == DIRECT_COPY)) {
16419 method = DRAW_AND_COPY;
16420 }
16421
16403 if (feature_info_->feature_flags().desktop_srgb_support) { 16422 if (feature_info_->feature_flags().desktop_srgb_support) {
16404 bool enable_framebuffer_srgb = 16423 bool enable_framebuffer_srgb =
16405 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB || 16424 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB ||
16406 GetColorEncodingFromInternalFormat(internal_format) == GL_SRGB; 16425 GetColorEncodingFromInternalFormat(internal_format) == GL_SRGB;
16407 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb); 16426 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
16408 } 16427 }
16409 16428
16410 int source_width = 0; 16429 int source_width = 0;
16411 int source_height = 0; 16430 int source_height = 0;
16412 gl::GLImage* image = 16431 gl::GLImage* image =
16413 source_texture->GetLevelImage(source_target, 0); 16432 source_texture->GetLevelImage(source_target, source_level);
16414 if (image) { 16433 if (image) {
16415 gfx::Size size = image->GetSize(); 16434 gfx::Size size = image->GetSize();
16416 source_width = size.width(); 16435 source_width = size.width();
16417 source_height = size.height(); 16436 source_height = size.height();
16418 if (source_width <= 0 || source_height <= 0) { 16437 if (source_width <= 0 || source_height <= 0) {
16419 LOCAL_SET_GL_ERROR( 16438 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size");
16420 GL_INVALID_VALUE,
16421 "glCopyTextureChromium", "invalid image size");
16422 return; 16439 return;
16423 } 16440 }
16424 } else { 16441 } else {
16425 if (!source_texture->GetLevelSize(source_target, 0, 16442 if (!source_texture->GetLevelSize(source_target, source_level,
16426 &source_width, &source_height, nullptr)) { 16443 &source_width, &source_height, nullptr)) {
16427 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, 16444 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16428 "glCopyTextureChromium", 16445 "source texture has no data for level");
16429 "source texture has no level 0");
16430 return; 16446 return;
16431 } 16447 }
16432 16448
16433 // Check that this type of texture is allowed. 16449 // Check that this type of texture is allowed.
16434 if (!texture_manager()->ValidForTarget(source_target, 0, 16450 if (!texture_manager()->ValidForTarget(source_target, source_level,
16435 source_width, source_height, 1)) { 16451 source_width, source_height, 1)) {
16436 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions"); 16452 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
16437 return; 16453 return;
16438 } 16454 }
16439 } 16455 }
16440 16456
16441 if (dest_texture->IsImmutable()) { 16457 if (dest_texture->IsImmutable()) {
16442 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, 16458 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
16443 "texture is immutable"); 16459 "texture is immutable");
16444 return; 16460 return;
16445 } 16461 }
16446 16462
16447 // Clear the source texture if necessary. 16463 // Clear the source texture if necessary.
16448 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, 16464 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
16449 source_target, 0)) { 16465 source_target, source_level)) {
16450 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, "dimensions too big"); 16466 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, "dimensions too big");
16451 return; 16467 return;
16452 } 16468 }
16453 16469
16454 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) 16470 if (!InitializeCopyTextureCHROMIUM(kFunctionName))
16455 return; 16471 return;
16456 16472
16457 GLenum dest_type_previous = dest_type; 16473 GLenum dest_type_previous = dest_type;
16458 GLenum dest_internal_format = internal_format; 16474 GLenum dest_internal_format = internal_format;
16459 int dest_width = 0; 16475 int dest_width = 0;
16460 int dest_height = 0; 16476 int dest_height = 0;
16461 bool dest_level_defined = dest_texture->GetLevelSize( 16477 bool dest_level_defined = dest_texture->GetLevelSize(
16462 dest_target, 0, &dest_width, &dest_height, nullptr); 16478 dest_target, dest_level, &dest_width, &dest_height, nullptr);
16463 16479
16464 if (dest_level_defined) { 16480 if (dest_level_defined) {
16465 dest_texture->GetLevelType(dest_target, 0, &dest_type_previous, 16481 dest_texture->GetLevelType(dest_target, dest_level, &dest_type_previous,
16466 &dest_internal_format); 16482 &dest_internal_format);
16467 } 16483 }
16468 16484
16469 // Resize the destination texture to the dimensions of the source texture. 16485 // Resize the destination texture to the dimensions of the source texture.
16470 if (!dest_level_defined || dest_width != source_width || 16486 if (!dest_level_defined || dest_width != source_width ||
16471 dest_height != source_height || 16487 dest_height != source_height ||
16472 dest_internal_format != internal_format || 16488 dest_internal_format != internal_format ||
16473 dest_type_previous != dest_type) { 16489 dest_type_previous != dest_type) {
16474 // Ensure that the glTexImage2D succeeds. 16490 // Ensure that the glTexImage2D succeeds.
16475 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); 16491 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName);
16476 glBindTexture(dest_target, dest_texture->service_id()); 16492 glBindTexture(dest_target, dest_texture->service_id());
16477 glTexImage2D(dest_target, 0, TextureManager::AdjustTexInternalFormat( 16493 glTexImage2D(dest_target, dest_level,
16478 feature_info_.get(), internal_format), 16494 TextureManager::AdjustTexInternalFormat(feature_info_.get(),
16495 internal_format),
16479 source_width, source_height, 0, 16496 source_width, source_height, 0,
16480 TextureManager::AdjustTexFormat(feature_info_.get(), format), 16497 TextureManager::AdjustTexFormat(feature_info_.get(), format),
16481 dest_type, NULL); 16498 dest_type, nullptr);
16482 GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); 16499 GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName);
16483 if (error != GL_NO_ERROR) { 16500 if (error != GL_NO_ERROR) {
16484 RestoreCurrentTextureBindings(&state_, dest_target); 16501 RestoreCurrentTextureBindings(&state_, dest_target);
16485 return; 16502 return;
16486 } 16503 }
16487 16504
16488 texture_manager()->SetLevelInfo(dest_texture_ref, dest_target, 0, 16505 texture_manager()->SetLevelInfo(dest_texture_ref, dest_target, dest_level,
16489 internal_format, source_width, 16506 internal_format, source_width,
16490 source_height, 1, 0, format, dest_type, 16507 source_height, 1, 0, format, dest_type,
16491 gfx::Rect(source_width, source_height)); 16508 gfx::Rect(source_width, source_height));
16492 dest_texture->ApplyFormatWorkarounds(feature_info_.get()); 16509 dest_texture->ApplyFormatWorkarounds(feature_info_.get());
16493 } else { 16510 } else {
16494 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, true); 16511 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target,
16512 dest_level, true);
16495 } 16513 }
16496 16514
16497 // Try using GLImage::CopyTexImage when possible. 16515 // Try using GLImage::CopyTexImage when possible.
16498 bool unpack_premultiply_alpha_change = 16516 bool unpack_premultiply_alpha_change =
16499 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0; 16517 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
16500 if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) { 16518 // TODO(qiankun.miao@intel.com): Support level > 0 for CopyTexImage.
16519 if (image && dest_level == 0 && !unpack_flip_y &&
16520 !unpack_premultiply_alpha_change) {
16501 glBindTexture(dest_target, dest_texture->service_id()); 16521 glBindTexture(dest_target, dest_texture->service_id());
16502 if (image->CopyTexImage(dest_target)) 16522 if (image->CopyTexImage(dest_target))
16503 return; 16523 return;
16504 } 16524 }
16505 16525
16506 DoCopyTexImageIfNeeded(source_texture, source_target); 16526 DoCopyTexImageIfNeeded(source_texture, source_target);
16507 16527
16508 // GL_TEXTURE_EXTERNAL_OES texture requires that we apply a transform matrix 16528 // GL_TEXTURE_EXTERNAL_OES texture requires that we apply a transform matrix
16509 // before presenting. 16529 // before presenting.
16510 if (source_target == GL_TEXTURE_EXTERNAL_OES) { 16530 if (source_target == GL_TEXTURE_EXTERNAL_OES) {
16511 if (GLStreamTextureImage* image = 16531 if (GLStreamTextureImage* image =
16512 source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES, 16532 source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
16513 0)) { 16533 source_level)) {
16514 GLfloat transform_matrix[16]; 16534 GLfloat transform_matrix[16];
16515 image->GetTextureMatrix(transform_matrix); 16535 image->GetTextureMatrix(transform_matrix);
16516 copy_texture_CHROMIUM_->DoCopyTextureWithTransform( 16536 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
16517 this, source_target, source_texture->service_id(), 16537 this, source_target, source_texture->service_id(), source_level,
16518 source_internal_format, dest_target, dest_texture->service_id(), 16538 source_internal_format, dest_target, dest_texture->service_id(),
16519 internal_format, source_width, source_height, 16539 dest_level, internal_format, source_width, source_height,
16520 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE, 16540 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
16521 unpack_unmultiply_alpha == GL_TRUE, transform_matrix); 16541 unpack_unmultiply_alpha == GL_TRUE, transform_matrix);
16522 return; 16542 return;
16523 } 16543 }
16524 } 16544 }
16525 16545
16526 copy_texture_CHROMIUM_->DoCopyTexture( 16546 copy_texture_CHROMIUM_->DoCopyTexture(
16527 this, source_target, source_texture->service_id(), source_internal_format, 16547 this, source_target, source_texture->service_id(), source_level,
16528 dest_target, dest_texture->service_id(), internal_format, source_width, 16548 source_internal_format, dest_target, dest_texture->service_id(),
16529 source_height, unpack_flip_y == GL_TRUE, 16549 dest_level, internal_format, source_width, source_height,
16530 unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE, 16550 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
16531 method); 16551 unpack_unmultiply_alpha == GL_TRUE, method);
16532 } 16552 }
16533 16553
16534 void GLES2DecoderImpl::DoCopySubTextureCHROMIUM( 16554 void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
16535 GLuint source_id, 16555 GLuint source_id,
16536 GLint source_level, 16556 GLint source_level,
16537 GLuint dest_id, 16557 GLuint dest_id,
16538 GLint dest_level, 16558 GLint dest_level,
16539 GLint xoffset, 16559 GLint xoffset,
16540 GLint yoffset, 16560 GLint yoffset,
16541 GLint x, 16561 GLint x,
16542 GLint y, 16562 GLint y,
16543 GLsizei width, 16563 GLsizei width,
16544 GLsizei height, 16564 GLsizei height,
16545 GLboolean unpack_flip_y, 16565 GLboolean unpack_flip_y,
16546 GLboolean unpack_premultiply_alpha, 16566 GLboolean unpack_premultiply_alpha,
16547 GLboolean unpack_unmultiply_alpha) { 16567 GLboolean unpack_unmultiply_alpha) {
16548 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM"); 16568 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
16549 16569
16550 // TODO(qiankun.miao@intel.com): Remove this after level > 0 support is
16551 // implemented. See: https://crbug.com/612542.
16552 DCHECK(source_level == 0);
16553 DCHECK(dest_level == 0);
16554
16555 static const char kFunctionName[] = "glCopySubTextureCHROMIUM"; 16570 static const char kFunctionName[] = "glCopySubTextureCHROMIUM";
16556 TextureRef* source_texture_ref = GetTexture(source_id); 16571 TextureRef* source_texture_ref = GetTexture(source_id);
16557 TextureRef* dest_texture_ref = GetTexture(dest_id); 16572 TextureRef* dest_texture_ref = GetTexture(dest_id);
16558 16573
16559 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref, 16574 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref,
16560 dest_texture_ref)) { 16575 dest_texture_ref)) {
16561 return; 16576 return;
16562 } 16577 }
16563 16578
16579 if (source_level < 0 || dest_level < 0 ||
16580 (feature_info_->IsWebGL1OrES2Context() && source_level > 0)) {
16581 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16582 "source_level or dest_level out of range");
16583 return;
16584 }
16585
16564 Texture* source_texture = source_texture_ref->texture(); 16586 Texture* source_texture = source_texture_ref->texture();
16565 Texture* dest_texture = dest_texture_ref->texture(); 16587 Texture* dest_texture = dest_texture_ref->texture();
16566 GLenum source_target = source_texture->target(); 16588 GLenum source_target = source_texture->target();
16567 GLenum dest_target = dest_texture->target(); 16589 GLenum dest_target = dest_texture->target();
16568 int source_width = 0; 16590 int source_width = 0;
16569 int source_height = 0; 16591 int source_height = 0;
16570 gl::GLImage* image = 16592 gl::GLImage* image =
16571 source_texture->GetLevelImage(source_target, 0); 16593 source_texture->GetLevelImage(source_target, source_level);
16572 if (image) { 16594 if (image) {
16573 gfx::Size size = image->GetSize(); 16595 gfx::Size size = image->GetSize();
16574 source_width = size.width(); 16596 source_width = size.width();
16575 source_height = size.height(); 16597 source_height = size.height();
16576 if (source_width <= 0 || source_height <= 0) { 16598 if (source_width <= 0 || source_height <= 0) {
16577 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size"); 16599 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size");
16578 return; 16600 return;
16579 } 16601 }
16580 16602
16581 // Ideally we should not need to check that the sub-texture copy rectangle 16603 // Ideally we should not need to check that the sub-texture copy rectangle
16582 // is valid in two different ways, here and below. However currently there 16604 // is valid in two different ways, here and below. However currently there
16583 // is no guarantee that a texture backed by a GLImage will have sensible 16605 // is no guarantee that a texture backed by a GLImage will have sensible
16584 // level info. If this synchronization were to be enforced then this and 16606 // level info. If this synchronization were to be enforced then this and
16585 // other functions in this file could be cleaned up. 16607 // other functions in this file could be cleaned up.
16586 // See: https://crbug.com/586476 16608 // See: https://crbug.com/586476
16587 int32_t max_x; 16609 int32_t max_x;
16588 int32_t max_y; 16610 int32_t max_y;
16589 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y) || 16611 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y) ||
16590 x < 0 || y < 0 || max_x > source_width || max_y > source_height) { 16612 x < 0 || y < 0 || max_x > source_width || max_y > source_height) {
16591 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, 16613 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16592 "source texture bad dimensions"); 16614 "source texture bad dimensions");
16593 return; 16615 return;
16594 } 16616 }
16595 } else { 16617 } else {
16596 if (!source_texture->GetLevelSize(source_target, 0, 16618 if (!source_texture->GetLevelSize(source_target, source_level,
16597 &source_width, &source_height, nullptr)) { 16619 &source_width, &source_height, nullptr)) {
16598 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, 16620 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16599 "source texture has no level 0"); 16621 "source texture has no data for level");
16600 return; 16622 return;
16601 } 16623 }
16602 16624
16603 // Check that this type of texture is allowed. 16625 // Check that this type of texture is allowed.
16604 if (!texture_manager()->ValidForTarget(source_target, 0, 16626 if (!texture_manager()->ValidForTarget(source_target, source_level,
16605 source_width, source_height, 1)) { 16627 source_width, source_height, 1)) {
16606 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, 16628 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16607 "source texture bad dimensions"); 16629 "source texture bad dimensions");
16608 return; 16630 return;
16609 } 16631 }
16610 16632
16611 if (!source_texture->ValidForTexture(source_target, 0, x, y, 0, width, 16633 if (!source_texture->ValidForTexture(source_target, source_level, x, y, 0,
16612 height, 1)) { 16634 width, height, 1)) {
16613 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, 16635 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16614 "source texture bad dimensions."); 16636 "source texture bad dimensions.");
16615 return; 16637 return;
16616 } 16638 }
16617 } 16639 }
16618 16640
16619 GLenum source_type = 0; 16641 GLenum source_type = 0;
16620 GLenum source_internal_format = 0; 16642 GLenum source_internal_format = 0;
16621 source_texture->GetLevelType(source_target, 0, &source_type, 16643 source_texture->GetLevelType(source_target, source_level, &source_type,
16622 &source_internal_format); 16644 &source_internal_format);
16623 16645
16624 GLenum dest_type = 0; 16646 GLenum dest_type = 0;
16625 GLenum dest_internal_format = 0; 16647 GLenum dest_internal_format = 0;
16626 bool dest_level_defined = dest_texture->GetLevelType( 16648 bool dest_level_defined = dest_texture->GetLevelType(
16627 dest_target, 0, &dest_type, &dest_internal_format); 16649 dest_target, dest_level, &dest_type, &dest_internal_format);
16628 if (!dest_level_defined) { 16650 if (!dest_level_defined) {
16629 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, 16651 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
16630 "destination texture is not defined"); 16652 "destination texture is not defined");
16631 return; 16653 return;
16632 } 16654 }
16633 if (!dest_texture->ValidForTexture(dest_target, 0, xoffset, 16655 if (!dest_texture->ValidForTexture(dest_target, dest_level, xoffset, yoffset,
16634 yoffset, 0, width, height, 1)) { 16656 0, width, height, 1)) {
16635 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, 16657 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
16636 "destination texture bad dimensions."); 16658 "destination texture bad dimensions.");
16637 return; 16659 return;
16638 } 16660 }
16639 16661
16640 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats( 16662 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats(
16641 kFunctionName, source_texture_ref, dest_internal_format); 16663 kFunctionName, source_texture_ref, source_level, dest_internal_format);
16642 // INVALID_OPERATION is already generated by 16664 // INVALID_OPERATION is already generated by
16643 // ValidateCopyTextureCHROMIUMInternalFormats. 16665 // ValidateCopyTextureCHROMIUMInternalFormats.
16644 if (NOT_COPYABLE == method) { 16666 if (method == NOT_COPYABLE) {
16645 return; 16667 return;
16646 } 16668 }
16647 16669
16670 // Draw to a fbo attaching level 0 of an intermediate texture,
16671 // then copy from the fbo to dest texture level with glCopyTexImage2D.
16672 // For WebGL 1.0 or OpenGL ES 2.0, DIRECT_DRAW path isn't available for
16673 // dest_level > 0 due to level > 0 isn't supported by glFramebufferTexture2D
16674 // in ES2 context. Go to DRAW_AND_COPY path in this case.
16675 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
16676 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
16677 // 0 are not available due to a framebuffer completeness bug:
16678 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and
16679 // OpenGL ES 3.0 can be lifted.
16680 if ((dest_level > 0 && method == DIRECT_DRAW) ||
16681 (source_level > 0 && method == DIRECT_COPY)) {
16682 method = DRAW_AND_COPY;
16683 }
16684
16648 if (feature_info_->feature_flags().desktop_srgb_support) { 16685 if (feature_info_->feature_flags().desktop_srgb_support) {
16649 bool enable_framebuffer_srgb = 16686 bool enable_framebuffer_srgb =
16650 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB || 16687 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB ||
16651 GetColorEncodingFromInternalFormat(dest_internal_format) == GL_SRGB; 16688 GetColorEncodingFromInternalFormat(dest_internal_format) == GL_SRGB;
16652 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb); 16689 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
16653 } 16690 }
16654 16691
16655 // Clear the source texture if necessary. 16692 // Clear the source texture if necessary.
16656 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, 16693 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
16657 source_target, 0)) { 16694 source_target, source_level)) {
16658 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, 16695 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName,
16659 "source texture dimensions too big"); 16696 "source texture dimensions too big");
16660 return; 16697 return;
16661 } 16698 }
16662 16699
16663 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) 16700 if (!InitializeCopyTextureCHROMIUM(kFunctionName))
16664 return; 16701 return;
16665 16702
16666 int dest_width = 0; 16703 int dest_width = 0;
16667 int dest_height = 0; 16704 int dest_height = 0;
16668 bool ok = dest_texture->GetLevelSize( 16705 bool ok = dest_texture->GetLevelSize(dest_target, dest_level, &dest_width,
16669 dest_target, 0, &dest_width, &dest_height, nullptr); 16706 &dest_height, nullptr);
16670 DCHECK(ok); 16707 DCHECK(ok);
16671 if (xoffset != 0 || yoffset != 0 || width != dest_width || 16708 if (xoffset != 0 || yoffset != 0 || width != dest_width ||
16672 height != dest_height) { 16709 height != dest_height) {
16673 gfx::Rect cleared_rect; 16710 gfx::Rect cleared_rect;
16674 if (TextureManager::CombineAdjacentRects( 16711 if (TextureManager::CombineAdjacentRects(
16675 dest_texture->GetLevelClearedRect(dest_target, 0), 16712 dest_texture->GetLevelClearedRect(dest_target, dest_level),
16676 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) { 16713 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
16677 DCHECK_GE( 16714 DCHECK_GE(cleared_rect.size().GetArea(),
16678 cleared_rect.size().GetArea(), 16715 dest_texture->GetLevelClearedRect(dest_target, dest_level)
16679 dest_texture->GetLevelClearedRect(dest_target, 0).size().GetArea()); 16716 .size()
16680 texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target, 0, 16717 .GetArea());
16681 cleared_rect); 16718 texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target,
16719 dest_level, cleared_rect);
16682 } else { 16720 } else {
16683 // Otherwise clear part of texture level that is not already cleared. 16721 // Otherwise clear part of texture level that is not already cleared.
16684 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, 16722 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref,
16685 dest_target, 0)) { 16723 dest_target, dest_level)) {
16686 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, 16724 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName,
16687 "destination texture dimensions too big"); 16725 "destination texture dimensions too big");
16688 return; 16726 return;
16689 } 16727 }
16690 } 16728 }
16691 } else { 16729 } else {
16692 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, 16730 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target,
16693 true); 16731 dest_level, true);
16694 } 16732 }
16695 16733
16696 // Try using GLImage::CopyTexSubImage when possible. 16734 // Try using GLImage::CopyTexSubImage when possible.
16697 bool unpack_premultiply_alpha_change = 16735 bool unpack_premultiply_alpha_change =
16698 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0; 16736 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
16699 if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) { 16737 // TODO(qiankun.miao@intel.com): Support level > 0 for CopyTexSubImage.
16738 if (image && dest_level == 0 && !unpack_flip_y &&
16739 !unpack_premultiply_alpha_change) {
16700 ScopedTextureBinder binder( 16740 ScopedTextureBinder binder(
16701 &state_, dest_texture->service_id(), dest_target); 16741 &state_, dest_texture->service_id(), dest_target);
16702 if (image->CopyTexSubImage(dest_target, gfx::Point(xoffset, yoffset), 16742 if (image->CopyTexSubImage(dest_target, gfx::Point(xoffset, yoffset),
16703 gfx::Rect(x, y, width, height))) { 16743 gfx::Rect(x, y, width, height))) {
16704 return; 16744 return;
16705 } 16745 }
16706 } 16746 }
16707 16747
16708 DoCopyTexImageIfNeeded(source_texture, source_target); 16748 DoCopyTexImageIfNeeded(source_texture, source_target);
16709 16749
16710 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix 16750 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
16711 // before presenting. 16751 // before presenting.
16712 if (source_target == GL_TEXTURE_EXTERNAL_OES) { 16752 if (source_target == GL_TEXTURE_EXTERNAL_OES) {
16713 if (GLStreamTextureImage* image = 16753 if (GLStreamTextureImage* image =
16714 source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES, 16754 source_texture->GetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES,
16715 0)) { 16755 source_level)) {
16716 GLfloat transform_matrix[16]; 16756 GLfloat transform_matrix[16];
16717 image->GetTextureMatrix(transform_matrix); 16757 image->GetTextureMatrix(transform_matrix);
16718 copy_texture_CHROMIUM_->DoCopySubTextureWithTransform( 16758 copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
16719 this, source_target, source_texture->service_id(), 16759 this, source_target, source_texture->service_id(), source_level,
16720 source_internal_format, dest_target, dest_texture->service_id(), 16760 source_internal_format, dest_target, dest_texture->service_id(),
16721 dest_internal_format, xoffset, yoffset, x, y, width, height, 16761 dest_level, dest_internal_format, xoffset, yoffset, x, y, width,
16722 dest_width, dest_height, source_width, source_height, 16762 height, dest_width, dest_height, source_width, source_height,
16723 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE, 16763 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
16724 unpack_unmultiply_alpha == GL_TRUE, transform_matrix); 16764 unpack_unmultiply_alpha == GL_TRUE, transform_matrix);
16725 return; 16765 return;
16726 } 16766 }
16727 } 16767 }
16728 copy_texture_CHROMIUM_->DoCopySubTexture( 16768 copy_texture_CHROMIUM_->DoCopySubTexture(
16729 this, source_target, source_texture->service_id(), source_internal_format, 16769 this, source_target, source_texture->service_id(), source_level,
16730 dest_target, dest_texture->service_id(), dest_internal_format, xoffset, 16770 source_internal_format, dest_target, dest_texture->service_id(),
16731 yoffset, x, y, width, height, dest_width, dest_height, source_width, 16771 dest_level, dest_internal_format, xoffset, yoffset, x, y, width, height,
16732 source_height, unpack_flip_y == GL_TRUE, 16772 dest_width, dest_height, source_width, source_height,
16733 unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE, 16773 unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
16734 method); 16774 unpack_unmultiply_alpha == GL_TRUE, method);
16735 } 16775 }
16736 16776
16737 bool GLES2DecoderImpl::InitializeCopyTexImageBlitter( 16777 bool GLES2DecoderImpl::InitializeCopyTexImageBlitter(
16738 const char* function_name) { 16778 const char* function_name) {
16739 if (!copy_tex_image_blit_.get()) { 16779 if (!copy_tex_image_blit_.get()) {
16740 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 16780 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
16741 copy_tex_image_blit_.reset( 16781 copy_tex_image_blit_.reset(
16742 new CopyTexImageResourceManager(feature_info_.get())); 16782 new CopyTexImageResourceManager(feature_info_.get()));
16743 copy_tex_image_blit_->Initialize(this); 16783 copy_tex_image_blit_->Initialize(this);
16744 if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) 16784 if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR)
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
16896 RestoreCurrentTextureBindings(&state_, dest_texture->target()); 16936 RestoreCurrentTextureBindings(&state_, dest_texture->target());
16897 return; 16937 return;
16898 } 16938 }
16899 16939
16900 texture_manager()->SetLevelInfo( 16940 texture_manager()->SetLevelInfo(
16901 dest_texture_ref, dest_texture->target(), 0, GL_RGBA, source_width, 16941 dest_texture_ref, dest_texture->target(), 0, GL_RGBA, source_width,
16902 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 16942 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
16903 gfx::Rect(source_width, source_height)); 16943 gfx::Rect(source_width, source_height));
16904 16944
16905 copy_texture_CHROMIUM_->DoCopyTexture( 16945 copy_texture_CHROMIUM_->DoCopyTexture(
16906 this, source_texture->target(), source_texture->service_id(), 16946 this, source_texture->target(), source_texture->service_id(), 0,
16907 source_internal_format, dest_texture->target(), 16947 source_internal_format, dest_texture->target(),
16908 dest_texture->service_id(), GL_RGBA, source_width, source_height, false, 16948 dest_texture->service_id(), 0, GL_RGBA, source_width, source_height,
16909 false, false, DIRECT_DRAW); 16949 false, false, false, DIRECT_DRAW);
16910 } 16950 }
16911 16951
16912 void GLES2DecoderImpl::TexStorageImpl(GLenum target, 16952 void GLES2DecoderImpl::TexStorageImpl(GLenum target,
16913 GLsizei levels, 16953 GLsizei levels,
16914 GLenum internal_format, 16954 GLenum internal_format,
16915 GLsizei width, 16955 GLsizei width,
16916 GLsizei height, 16956 GLsizei height,
16917 GLsizei depth, 16957 GLsizei depth,
16918 ContextState::Dimension dimension, 16958 ContextState::Dimension dimension,
16919 const char* function_name) { 16959 const char* function_name) {
(...skipping 2231 matching lines...) Expand 10 before | Expand all | Expand 10 after
19151 } 19191 }
19152 19192
19153 // Include the auto-generated part of this file. We split this because it means 19193 // Include the auto-generated part of this file. We split this because it means
19154 // we can easily edit the non-auto generated parts right here in this file 19194 // we can easily edit the non-auto generated parts right here in this file
19155 // instead of having to edit some template or the code generator. 19195 // instead of having to edit some template or the code generator.
19156 #include "base/macros.h" 19196 #include "base/macros.h"
19157 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 19197 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
19158 19198
19159 } // namespace gles2 19199 } // namespace gles2
19160 } // namespace gpu 19200 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698