Chromium Code Reviews| 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/texture_manager.h" | 5 #include "gpu/command_buffer/service/texture_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 } | 308 } |
| 309 | 309 |
| 310 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. | 310 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. |
| 311 GLuint ToGLuint(const void* ptr) { | 311 GLuint ToGLuint(const void* ptr) { |
| 312 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); | 312 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); |
| 313 } | 313 } |
| 314 | 314 |
| 315 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator = | 315 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator = |
| 316 LAZY_INSTANCE_INITIALIZER; | 316 LAZY_INSTANCE_INITIALIZER; |
| 317 | 317 |
| 318 class ScopedResetPixelUnpackBuffer{ | |
| 319 public: | |
| 320 explicit ScopedResetPixelUnpackBuffer(ContextState* state) | |
| 321 : state_(state), | |
| 322 buffer_(nullptr) { | |
| 323 buffer_ = state->bound_pixel_unpack_buffer.get(); | |
| 324 if (buffer_) { | |
| 325 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | |
| 326 state_->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); | |
|
piman
2016/09/21 05:37:20
nit: I don't think we need to modify state_ here (
qiankun
2016/09/23 03:20:14
Removed state_ modification.
| |
| 327 } | |
| 328 } | |
| 329 | |
| 330 ~ScopedResetPixelUnpackBuffer() { | |
| 331 if (buffer_) { | |
| 332 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer_->service_id()); | |
| 333 state_->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, buffer_); | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 private: | |
| 338 ContextState* state_; | |
| 339 Buffer* buffer_; | |
| 340 }; | |
| 341 | |
| 318 } // namespace anonymous | 342 } // namespace anonymous |
| 319 | 343 |
| 320 TextureManager::DestructionObserver::DestructionObserver() {} | 344 TextureManager::DestructionObserver::DestructionObserver() {} |
| 321 | 345 |
| 322 TextureManager::DestructionObserver::~DestructionObserver() {} | 346 TextureManager::DestructionObserver::~DestructionObserver() {} |
| 323 | 347 |
| 324 TextureManager::~TextureManager() { | 348 TextureManager::~TextureManager() { |
| 325 for (unsigned int i = 0; i < destruction_observers_.size(); i++) | 349 for (unsigned int i = 0; i < destruction_observers_.size(); i++) |
| 326 destruction_observers_[i]->OnTextureManagerDestroying(this); | 350 destruction_observers_[i]->OnTextureManagerDestroying(this); |
| 327 | 351 |
| (...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2395 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name, | 2419 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name, |
| 2396 "out of memory"); | 2420 "out of memory"); |
| 2397 return false; | 2421 return false; |
| 2398 } | 2422 } |
| 2399 | 2423 |
| 2400 // Write the TextureReference since this is valid. | 2424 // Write the TextureReference since this is valid. |
| 2401 *texture_ref = local_texture_ref; | 2425 *texture_ref = local_texture_ref; |
| 2402 return true; | 2426 return true; |
| 2403 } | 2427 } |
| 2404 | 2428 |
| 2429 void TextureManager::DoCubeMapWorkaround( | |
| 2430 DecoderTextureState* texture_state, | |
| 2431 ContextState* state, | |
| 2432 DecoderFramebufferState* framebuffer_state, | |
| 2433 TextureRef* texture_ref, | |
| 2434 const char* function_name, | |
| 2435 const DoTexImageArguments& args) { | |
| 2436 // This workaround code does not work with an unpack buffer bound. | |
| 2437 ScopedResetPixelUnpackBuffer scoped_reset_pbo(state); | |
| 2438 | |
| 2439 std::vector<GLenum> undefined_faces; | |
| 2440 Texture* texture = texture_ref->texture(); | |
| 2441 if (texture_state->force_cube_complete) { | |
| 2442 int width = 0; | |
| 2443 int height = 0; | |
| 2444 for (unsigned i = 0; i < 6; i++) { | |
| 2445 GLenum target = static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); | |
| 2446 bool defined = texture->GetLevelSize( | |
| 2447 target, args.level, &width, &height, nullptr); | |
| 2448 if (!defined && target != args.target) | |
| 2449 undefined_faces.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); | |
| 2450 } | |
| 2451 } else { | |
| 2452 DCHECK(args.target != GL_TEXTURE_CUBE_MAP_POSITIVE_X); | |
| 2453 int width = 0; | |
| 2454 int height = 0; | |
| 2455 if (!texture->GetLevelSize(GL_TEXTURE_CUBE_MAP_POSITIVE_X, args.level, | |
| 2456 &width, &height, nullptr)) { | |
| 2457 undefined_faces.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X); | |
| 2458 } | |
| 2459 } | |
| 2460 if (!memory_type_tracker_->EnsureGPUMemoryAvailable( | |
| 2461 (undefined_faces.size() + 1) * args.pixels_size)) { | |
| 2462 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY, | |
| 2463 function_name, "out of memory"); | |
| 2464 return; | |
| 2465 } | |
| 2466 DoTexImageArguments new_args = args; | |
| 2467 std::unique_ptr<char[]> zero(new char[args.pixels_size]); | |
| 2468 memset(zero.get(), 0, args.pixels_size); | |
| 2469 for (GLenum face : undefined_faces) { | |
| 2470 new_args.target = face; | |
| 2471 new_args.pixels = zero.get(); | |
| 2472 DoTexImage(texture_state, state, framebuffer_state, | |
| 2473 function_name, texture_ref, new_args); | |
| 2474 texture->MarkLevelAsInternalWorkaround(face, args.level); | |
| 2475 } | |
| 2476 } | |
| 2477 | |
| 2405 void TextureManager::ValidateAndDoTexImage( | 2478 void TextureManager::ValidateAndDoTexImage( |
| 2406 DecoderTextureState* texture_state, | 2479 DecoderTextureState* texture_state, |
| 2407 ContextState* state, | 2480 ContextState* state, |
| 2408 DecoderFramebufferState* framebuffer_state, | 2481 DecoderFramebufferState* framebuffer_state, |
| 2409 const char* function_name, | 2482 const char* function_name, |
| 2410 const DoTexImageArguments& args) { | 2483 const DoTexImageArguments& args) { |
| 2411 TextureRef* texture_ref; | 2484 TextureRef* texture_ref; |
| 2412 if (!ValidateTexImage(state, function_name, args, &texture_ref)) { | 2485 if (!ValidateTexImage(state, function_name, args, &texture_ref)) { |
| 2413 return; | 2486 return; |
| 2414 } | 2487 } |
| 2415 | 2488 |
| 2416 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); | 2489 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); |
| 2417 | 2490 |
| 2418 // ValidateTexImage is passed already. | 2491 // ValidateTexImage is passed already. |
| 2419 Texture* texture = texture_ref->texture(); | 2492 Texture* texture = texture_ref->texture(); |
| 2420 bool need_cube_map_workaround = | 2493 bool need_cube_map_workaround = |
| 2421 !feature_info_->IsES3Enabled() && | 2494 !feature_info_->IsES3Enabled() && |
| 2422 texture->target() == GL_TEXTURE_CUBE_MAP && | 2495 texture->target() == GL_TEXTURE_CUBE_MAP && |
| 2423 (texture_state->force_cube_complete || | 2496 (texture_state->force_cube_complete || |
| 2424 (texture_state->force_cube_map_positive_x_allocation && | 2497 (texture_state->force_cube_map_positive_x_allocation && |
| 2425 args.target != GL_TEXTURE_CUBE_MAP_POSITIVE_X)); | 2498 args.target != GL_TEXTURE_CUBE_MAP_POSITIVE_X)); |
| 2426 if (need_cube_map_workaround && !buffer) { | 2499 if (need_cube_map_workaround && !buffer) { |
| 2427 // TODO(zmo): The following code does not work with an unpack buffer bound. | 2500 DoCubeMapWorkaround(texture_state, state, framebuffer_state, |
| 2428 std::vector<GLenum> undefined_faces; | 2501 texture_ref, function_name, args); |
| 2429 if (texture_state->force_cube_complete) { | |
| 2430 int width = 0; | |
| 2431 int height = 0; | |
| 2432 for (unsigned i = 0; i < 6; i++) { | |
| 2433 GLenum target = static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); | |
| 2434 bool defined = texture->GetLevelSize( | |
| 2435 target, args.level, &width, &height, nullptr); | |
| 2436 if (!defined && target != args.target) | |
| 2437 undefined_faces.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); | |
| 2438 } | |
| 2439 } else { | |
| 2440 DCHECK(texture_state->force_cube_map_positive_x_allocation && | |
| 2441 args.target != GL_TEXTURE_CUBE_MAP_POSITIVE_X); | |
| 2442 int width = 0; | |
| 2443 int height = 0; | |
| 2444 if (!texture->GetLevelSize(GL_TEXTURE_CUBE_MAP_POSITIVE_X, args.level, | |
| 2445 &width, &height, nullptr)) { | |
| 2446 undefined_faces.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X); | |
| 2447 } | |
| 2448 } | |
| 2449 if (!memory_type_tracker_->EnsureGPUMemoryAvailable( | |
| 2450 (undefined_faces.size() + 1) * args.pixels_size)) { | |
| 2451 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY, | |
| 2452 function_name, "out of memory"); | |
| 2453 return; | |
| 2454 } | |
| 2455 DoTexImageArguments new_args = args; | |
| 2456 std::unique_ptr<char[]> zero(new char[args.pixels_size]); | |
| 2457 memset(zero.get(), 0, args.pixels_size); | |
| 2458 for (GLenum face : undefined_faces) { | |
| 2459 new_args.target = face; | |
| 2460 new_args.pixels = zero.get(); | |
| 2461 DoTexImage(texture_state, state, framebuffer_state, | |
| 2462 function_name, texture_ref, new_args); | |
| 2463 texture->MarkLevelAsInternalWorkaround(face, args.level); | |
| 2464 } | |
| 2465 } | 2502 } |
| 2466 | 2503 |
| 2467 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer && | 2504 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer && |
| 2468 buffer) { | 2505 buffer) { |
| 2469 ContextState::Dimension dimension = | 2506 ContextState::Dimension dimension = |
| 2470 (args.command_type == DoTexImageArguments::kTexImage3D) | 2507 (args.command_type == DoTexImageArguments::kTexImage3D) |
| 2471 ? ContextState::k3D | 2508 ? ContextState::k3D |
| 2472 : ContextState::k2D; | 2509 : ContextState::k2D; |
| 2473 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); | 2510 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); |
| 2474 if (unpack_params.row_length != 0 && | 2511 if (unpack_params.row_length != 0 && |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3418 uint32_t TextureManager::GetServiceIdGeneration() const { | 3455 uint32_t TextureManager::GetServiceIdGeneration() const { |
| 3419 return current_service_id_generation_; | 3456 return current_service_id_generation_; |
| 3420 } | 3457 } |
| 3421 | 3458 |
| 3422 void TextureManager::IncrementServiceIdGeneration() { | 3459 void TextureManager::IncrementServiceIdGeneration() { |
| 3423 current_service_id_generation_++; | 3460 current_service_id_generation_++; |
| 3424 } | 3461 } |
| 3425 | 3462 |
| 3426 } // namespace gles2 | 3463 } // namespace gles2 |
| 3427 } // namespace gpu | 3464 } // namespace gpu |
| OLD | NEW |