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 |