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

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

Issue 1872663002: Enable TexStorage on Desktop GL lower than 4.2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 GLint x, 976 GLint x,
977 GLint y, 977 GLint y,
978 GLsizei width, 978 GLsizei width,
979 GLsizei height, 979 GLsizei height,
980 GLboolean unpack_flip_y, 980 GLboolean unpack_flip_y,
981 GLboolean unpack_premultiply_alpha, 981 GLboolean unpack_premultiply_alpha,
982 GLboolean unpack_unmultiply_alpha); 982 GLboolean unpack_unmultiply_alpha);
983 983
984 void DoCompressedCopyTextureCHROMIUM(GLuint source_id, GLuint dest_id); 984 void DoCompressedCopyTextureCHROMIUM(GLuint source_id, GLuint dest_id);
985 985
986 // Helper for DoTexStorage2DEXT and DoTexStorage3D.
987 void TexStorageImpl(
988 GLenum target, GLint levels, GLenum internal_format,
989 GLsizei width, GLsizei height, GLsizei depth,
990 ContextState::Dimension dimension, const char* function_name);
991
986 // Wrapper for TexStorage2DEXT. 992 // Wrapper for TexStorage2DEXT.
987 void DoTexStorage2DEXT( 993 void DoTexStorage2DEXT(
988 GLenum target, 994 GLenum target,
989 GLint levels, 995 GLint levels,
990 GLenum internal_format, 996 GLenum internal_format,
991 GLsizei width, 997 GLsizei width,
992 GLsizei height); 998 GLsizei height);
993 999
994 // Wrapper for TexStorage3D. 1000 // Wrapper for TexStorage3D.
995 void DoTexStorage3D( 1001 void DoTexStorage3D(
(...skipping 13295 matching lines...) Expand 10 before | Expand all | Expand 10 after
14291 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 14297 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
14292 gfx::Rect(source_width, source_height)); 14298 gfx::Rect(source_width, source_height));
14293 14299
14294 copy_texture_CHROMIUM_->DoCopyTexture( 14300 copy_texture_CHROMIUM_->DoCopyTexture(
14295 this, source_texture->target(), source_texture->service_id(), 14301 this, source_texture->target(), source_texture->service_id(),
14296 source_internal_format, dest_texture->target(), 14302 source_internal_format, dest_texture->target(),
14297 dest_texture->service_id(), GL_RGBA, source_width, source_height, false, 14303 dest_texture->service_id(), GL_RGBA, source_width, source_height, false,
14298 false, false); 14304 false, false);
14299 } 14305 }
14300 14306
14301 void GLES2DecoderImpl::DoTexStorage2DEXT( 14307 void GLES2DecoderImpl::TexStorageImpl(
14302 GLenum target, 14308 GLenum target, GLint levels, GLenum internal_format,
14303 GLint levels, 14309 GLsizei width, GLsizei height, GLsizei depth,
14304 GLenum internal_format, 14310 ContextState::Dimension dimension, const char* function_name) {
14305 GLsizei width, 14311 if (dimension == ContextState::k2D) {
14306 GLsizei height) { 14312 if (!validators_->texture_bind_target.IsValid(target)) {
14307 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT", 14313 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
14308 "width", width, "height", height); 14314 return;
14309 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || 14315 }
14310 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { 14316 } else {
14317 if (!validators_->texture_3_d_target.IsValid(target)) {
14318 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
14319 return;
14320 }
14321 }
14322 if (levels <= 0) {
14323 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "levels <= 0");
14324 return;
14325 }
14326 if (!validators_->texture_internal_format_storage.IsValid(internal_format)) {
14327 LOCAL_SET_GL_ERROR_INVALID_ENUM(
14328 function_name, internal_format, "internal_format");
14329 return;
14330 }
14331 bool is_compressed_format;
14332 switch (internal_format) {
14333 case GL_COMPRESSED_R11_EAC:
14334 case GL_COMPRESSED_SIGNED_R11_EAC:
14335 case GL_COMPRESSED_RG11_EAC:
14336 case GL_COMPRESSED_SIGNED_RG11_EAC:
14337 case GL_COMPRESSED_RGB8_ETC2:
14338 case GL_COMPRESSED_SRGB8_ETC2:
14339 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
14340 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
14341 case GL_COMPRESSED_RGBA8_ETC2_EAC:
14342 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
14343 is_compressed_format = true;
14344 if (target == GL_TEXTURE_3D) {
14345 LOCAL_SET_GL_ERROR(
14346 GL_INVALID_OPERATION, function_name, "target invalid for format");
14347 return;
14348 }
14349 break;
14350 default:
14351 is_compressed_format = false;
14352 break;
14353 }
14354 if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
14355 TextureManager::ComputeMipMapCount(
14356 target, width, height, depth) < levels) {
14311 LOCAL_SET_GL_ERROR( 14357 LOCAL_SET_GL_ERROR(
14312 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); 14358 GL_INVALID_VALUE, function_name, "dimensions out of range");
14313 return; 14359 return;
14314 } 14360 }
14315 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 14361 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
14316 &state_, target); 14362 &state_, target);
14317 if (!texture_ref) { 14363 if (!texture_ref) {
14318 LOCAL_SET_GL_ERROR( 14364 LOCAL_SET_GL_ERROR(
14319 GL_INVALID_OPERATION, 14365 GL_INVALID_OPERATION, function_name, "unknown texture for target");
14320 "glTexStorage2DEXT", "unknown texture for target");
14321 return; 14366 return;
14322 } 14367 }
14323 Texture* texture = texture_ref->texture(); 14368 Texture* texture = texture_ref->texture();
14324 if (texture->IsAttachedToFramebuffer()) {
14325 framebuffer_state_.clear_state_dirty = true;
14326 }
14327 if (texture->IsImmutable()) {
14328 LOCAL_SET_GL_ERROR(
14329 GL_INVALID_OPERATION,
14330 "glTexStorage2DEXT", "texture is immutable");
14331 return;
14332 }
14333
14334 GLenum format = TextureManager::ExtractFormatFromStorageFormat(
14335 internal_format);
14336 GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
14337
14338 {
14339 GLsizei level_width = width;
14340 GLsizei level_height = height;
14341 uint32_t estimated_size = 0;
14342 for (int ii = 0; ii < levels; ++ii) {
14343 uint32_t level_size = 0;
14344 if (!GLES2Util::ComputeImageDataSizes(
14345 level_width, level_height, 1, format, type, state_.unpack_alignment,
14346 &estimated_size, NULL, NULL) ||
14347 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
14348 LOCAL_SET_GL_ERROR(
14349 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
14350 return;
14351 }
14352 level_width = std::max(1, level_width >> 1);
14353 level_height = std::max(1, level_height >> 1);
14354 }
14355 if (!EnsureGPUMemoryAvailable(estimated_size)) {
14356 LOCAL_SET_GL_ERROR(
14357 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
14358 return;
14359 }
14360 }
14361
14362 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
14363 glTexStorage2DEXT(target, levels, internal_format, width, height);
14364 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
14365 if (error == GL_NO_ERROR) {
14366 GLsizei level_width = width;
14367 GLsizei level_height = height;
14368
14369 GLenum cur_format = feature_info_->IsES3Enabled() ?
14370 internal_format : format;
14371 for (int ii = 0; ii < levels; ++ii) {
14372 if (target == GL_TEXTURE_CUBE_MAP) {
14373 for (int jj = 0; jj < 6; ++jj) {
14374 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + jj;
14375 texture_manager()->SetLevelInfo(texture_ref, face, ii, cur_format,
14376 level_width, level_height, 1, 0,
14377 format, type, gfx::Rect());
14378 }
14379 } else {
14380 texture_manager()->SetLevelInfo(texture_ref, target, ii, cur_format,
14381 level_width, level_height, 1, 0,
14382 format, type, gfx::Rect());
14383 }
14384 level_width = std::max(1, level_width >> 1);
14385 level_height = std::max(1, level_height >> 1);
14386 }
14387 texture->SetImmutable(true);
14388 }
14389 }
14390
14391 void GLES2DecoderImpl::DoTexStorage3D(
14392 GLenum target,
14393 GLint levels,
14394 GLenum internal_format,
14395 GLsizei width,
14396 GLsizei height,
14397 GLsizei depth) {
14398 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage3D",
14399 "widthXheight", width * height, "depth", depth);
14400 if (!validators_->texture_3_d_target.IsValid(target)) {
14401 LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage3D", target, "target");
14402 return;
14403 }
14404 if (levels <= 0) {
14405 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "levels <= 0");
14406 return;
14407 }
14408 if (!validators_->texture_internal_format_storage.IsValid(internal_format)) {
14409 LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage3D", internal_format,
14410 "internal_format");
14411 return;
14412 }
14413 if (width <= 0) {
14414 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "width <= 0");
14415 return;
14416 }
14417 if (height <= 0) {
14418 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "height <= 0");
14419 return;
14420 }
14421 if (depth <= 0) {
14422 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "depth <= 0");
14423 return;
14424 }
14425 if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
14426 TextureManager::ComputeMipMapCount(
14427 target, width, height, depth) < levels) {
14428 LOCAL_SET_GL_ERROR(
14429 GL_INVALID_VALUE, "glTexStorage3D", "dimensions out of range");
14430 return;
14431 }
14432 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
14433 &state_, target);
14434 if (!texture_ref) {
14435 LOCAL_SET_GL_ERROR(
14436 GL_INVALID_OPERATION,
14437 "glTexStorage3D", "unknown texture for target");
14438 return;
14439 }
14440 Texture* texture = texture_ref->texture();
14441 if (texture->IsAttachedToFramebuffer()) { 14369 if (texture->IsAttachedToFramebuffer()) {
14442 framebuffer_state_.clear_state_dirty = true; 14370 framebuffer_state_.clear_state_dirty = true;
14443 } 14371 }
14444 if (texture->IsImmutable()) { 14372 if (texture->IsImmutable()) {
14445 LOCAL_SET_GL_ERROR( 14373 LOCAL_SET_GL_ERROR(
14446 GL_INVALID_OPERATION, "glTexStorage3D", "texture is immutable"); 14374 GL_INVALID_OPERATION, function_name, "texture is immutable");
14447 return; 14375 return;
14448 } 14376 }
14449 14377
14450 GLenum format = TextureManager::ExtractFormatFromStorageFormat( 14378 GLenum format = TextureManager::ExtractFormatFromStorageFormat(
14451 internal_format); 14379 internal_format);
14452 GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format); 14380 GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
14453 14381
14382 std::vector<int32_t> level_size(levels);
14383 {
14384 GLsizei level_width = width;
14385 GLsizei level_height = height;
14386 GLsizei level_depth = depth;
14387 base::CheckedNumeric<uint32_t> estimated_size(0);
14388 PixelStoreParams params;
14389 params.alignment = 1;
14390 for (int ii = 0; ii < levels; ++ii) {
14391 uint32_t size;
14392 if (is_compressed_format) {
14393 if (!GetCompressedTexSizeInBytes(function_name,
14394 level_width, level_height, level_depth,
14395 internal_format, &level_size[ii])) {
14396 // GetCompressedTexSizeInBytes() already generates a GL error.
14397 return;
14398 }
14399 size = static_cast<uint32_t>(level_size[ii]);
14400 } else {
14401 if (!GLES2Util::ComputeImageDataSizesES3(level_width,
14402 level_height,
14403 level_depth,
14404 format, type,
14405 params,
14406 &size,
14407 nullptr, nullptr,
14408 nullptr, nullptr)) {
14409 LOCAL_SET_GL_ERROR(
14410 GL_OUT_OF_MEMORY, function_name, "dimensions too large");
14411 return;
14412 }
14413 }
14414 estimated_size += size;
14415 level_width = std::max(1, level_width >> 1);
14416 level_height = std::max(1, level_height >> 1);
14417 if (target == GL_TEXTURE_3D)
14418 level_depth = std::max(1, level_depth >> 1);
14419 }
14420 if (!estimated_size.IsValid() ||
14421 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) {
14422 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory");
14423 return;
14424 }
14425 }
14426
14427 // TODO(zmo): We might need to emulate TexStorage using TexImage or
14428 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying
14429 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
14430 if (dimension == ContextState::k2D) {
14431 glTexStorage2DEXT(target, levels, internal_format, width, height);
14432 } else {
14433 glTexStorage3D(target, levels, internal_format, width, height, depth);
14434 }
14435
14454 { 14436 {
14455 GLsizei level_width = width; 14437 GLsizei level_width = width;
14456 GLsizei level_height = height; 14438 GLsizei level_height = height;
14457 GLsizei level_depth = depth; 14439 GLsizei level_depth = depth;
14458 uint32_t estimated_size = 0; 14440 GLenum adjusted_format =
14441 feature_info_->IsES3Enabled() ? internal_format : format;
14459 for (int ii = 0; ii < levels; ++ii) { 14442 for (int ii = 0; ii < levels; ++ii) {
14460 uint32_t level_size = 0; 14443 if (target == GL_TEXTURE_CUBE_MAP) {
14461 if (!GLES2Util::ComputeImageDataSizes( 14444 for (int jj = 0; jj < 6; ++jj) {
14462 level_width, level_height, level_depth, format, type, 14445 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + jj;
14463 state_.unpack_alignment, 14446 texture_manager()->SetLevelInfo(texture_ref, face, ii,
14464 &estimated_size, NULL, NULL) || 14447 adjusted_format,
14465 !SafeAddUint32(estimated_size, level_size, &estimated_size)) { 14448 level_width, level_height, 1,
14466 LOCAL_SET_GL_ERROR( 14449 0, format, type, gfx::Rect());
14467 GL_OUT_OF_MEMORY, "glTexStorage3D", "dimensions too large"); 14450 }
14468 return; 14451 } else {
14452 texture_manager()->SetLevelInfo(texture_ref, target, ii,
14453 adjusted_format,
14454 level_width, level_height, level_depth,
14455 0, format, type, gfx::Rect());
14469 } 14456 }
14470 level_width = std::max(1, level_width >> 1); 14457 level_width = std::max(1, level_width >> 1);
14471 level_height = std::max(1, level_height >> 1); 14458 level_height = std::max(1, level_height >> 1);
14472 if (target == GL_TEXTURE_3D) 14459 if (target == GL_TEXTURE_3D)
14473 level_depth = std::max(1, level_depth >> 1);
14474 }
14475 if (!EnsureGPUMemoryAvailable(estimated_size)) {
14476 LOCAL_SET_GL_ERROR(
14477 GL_OUT_OF_MEMORY, "glTexStorage3D", "out of memory");
14478 return;
14479 }
14480 }
14481
14482 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage3D");
14483 glTexStorage3D(target, levels, internal_format, width, height, depth);
14484 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage3D");
14485 if (error == GL_NO_ERROR) {
14486 GLsizei level_width = width;
14487 GLsizei level_height = height;
14488 GLsizei level_depth = depth;
14489
14490 GLenum cur_format = feature_info_->IsES3Enabled() ?
14491 internal_format : format;
14492 for (int ii = 0; ii < levels; ++ii) {
14493 texture_manager()->SetLevelInfo(texture_ref, target, ii, cur_format,
14494 level_width, level_height, level_depth, 0,
14495 format, type, gfx::Rect());
14496 level_width = std::max(1, level_width >> 1);
14497 level_height = std::max(1, level_height >> 1);
14498 if (target == GL_TEXTURE_3D)
14499 level_depth = std::max(1, level_depth >> 1); 14460 level_depth = std::max(1, level_depth >> 1);
14500 } 14461 }
14501 texture->SetImmutable(true); 14462 texture->SetImmutable(true);
14502 } 14463 }
14503 } 14464 }
14504 14465
14466 void GLES2DecoderImpl::DoTexStorage2DEXT(
14467 GLenum target,
14468 GLint levels,
14469 GLenum internal_format,
14470 GLsizei width,
14471 GLsizei height) {
14472 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2D",
14473 "width", width, "height", height);
14474 TexStorageImpl(target, levels, internal_format, width, height, 1,
14475 ContextState::k2D, "glTexStorage2D");
14476 }
14477
14478 void GLES2DecoderImpl::DoTexStorage3D(
14479 GLenum target,
14480 GLint levels,
14481 GLenum internal_format,
14482 GLsizei width,
14483 GLsizei height,
14484 GLsizei depth) {
14485 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage3D",
14486 "widthXheight", width * height, "depth", depth);
14487 TexStorageImpl(target, levels, internal_format, width, height, depth,
14488 ContextState::k3D, "glTexStorage3D");
14489 }
14490
14505 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( 14491 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
14506 uint32_t immediate_data_size, 14492 uint32_t immediate_data_size,
14507 const void* cmd_data) { 14493 const void* cmd_data) {
14508 return error::kUnknownCommand; 14494 return error::kUnknownCommand;
14509 } 14495 }
14510 14496
14511 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, 14497 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
14512 const GLbyte* data) { 14498 const GLbyte* data) {
14513 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM", 14499 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
14514 "context", logger_.GetLogPrefix(), 14500 "context", logger_.GetLogPrefix(),
(...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after
16377 } 16363 }
16378 16364
16379 // Include the auto-generated part of this file. We split this because it means 16365 // Include the auto-generated part of this file. We split this because it means
16380 // we can easily edit the non-auto generated parts right here in this file 16366 // we can easily edit the non-auto generated parts right here in this file
16381 // instead of having to edit some template or the code generator. 16367 // instead of having to edit some template or the code generator.
16382 #include "base/macros.h" 16368 #include "base/macros.h"
16383 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 16369 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
16384 16370
16385 } // namespace gles2 16371 } // namespace gles2
16386 } // namespace gpu 16372 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698