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

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

Issue 1750123002: Upgrade Tex{Sub}Image{2|3}D to handle ES3 unpack parameters. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Attemp to fix random crashes on windows Created 4 years, 9 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
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 case GL_BLUE: 295 case GL_BLUE:
296 return swizzle->blue; 296 return swizzle->blue;
297 case GL_ALPHA: 297 case GL_ALPHA:
298 return swizzle->alpha; 298 return swizzle->alpha;
299 default: 299 default:
300 NOTREACHED(); 300 NOTREACHED();
301 return GL_NONE; 301 return GL_NONE;
302 } 302 }
303 } 303 }
304 304
305 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint.
306 GLuint ToGLuint(const void* ptr) {
307 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
308 }
309
305 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator = 310 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator =
306 LAZY_INSTANCE_INITIALIZER; 311 LAZY_INSTANCE_INITIALIZER;
307 312
308 } // namespace anonymous 313 } // namespace anonymous
309 314
310 TextureManager::DestructionObserver::DestructionObserver() {} 315 TextureManager::DestructionObserver::DestructionObserver() {}
311 316
312 TextureManager::DestructionObserver::~DestructionObserver() {} 317 TextureManager::DestructionObserver::~DestructionObserver() {}
313 318
314 TextureManager::~TextureManager() { 319 TextureManager::~TextureManager() {
(...skipping 1899 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 "unknown texture for target"); 2219 "unknown texture for target");
2215 return false; 2220 return false;
2216 } 2221 }
2217 if (local_texture_ref->texture()->IsImmutable()) { 2222 if (local_texture_ref->texture()->IsImmutable()) {
2218 ERRORSTATE_SET_GL_ERROR( 2223 ERRORSTATE_SET_GL_ERROR(
2219 error_state, GL_INVALID_OPERATION, function_name, 2224 error_state, GL_INVALID_OPERATION, function_name,
2220 "texture is immutable"); 2225 "texture is immutable");
2221 return false; 2226 return false;
2222 } 2227 }
2223 2228
2229 Buffer* buffer = state->bound_pixel_unpack_buffer.get();
2230 if (buffer) {
2231 if (buffer->GetMappedRange()) {
2232 ERRORSTATE_SET_GL_ERROR(
2233 error_state, GL_INVALID_OPERATION, function_name,
2234 "pixel unpack buffer should not be mapped to client memory");
2235 return error::kNoError;
2236 }
2237 base::CheckedNumeric<uint32_t> size = args.pixels_size;
2238 GLuint offset = ToGLuint(args.pixels);
2239 size += offset;
2240 if (!size.IsValid()) {
2241 ERRORSTATE_SET_GL_ERROR(
2242 error_state, GL_INVALID_VALUE, function_name,
2243 "size + offset overflow");
2244 return error::kNoError;
2245 }
2246 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2247 if (buffer_size < size.ValueOrDefault(0)) {
2248 ERRORSTATE_SET_GL_ERROR(
2249 error_state, GL_INVALID_OPERATION, function_name,
2250 "pixel unpack buffer is not large enough");
2251 return error::kNoError;
2252 }
2253 size_t type_size = GLES2Util::GetGLTypeSizeForTextures(args.type);
2254 DCHECK_LT(0u, type_size);
2255 if (offset % type_size != 0) {
2256 ERRORSTATE_SET_GL_ERROR(
2257 error_state, GL_INVALID_OPERATION, function_name,
2258 "offset is not evenly divisible by elements");
2259 return error::kNoError;
2260 }
2261 }
2262
2224 if (!memory_type_tracker_->EnsureGPUMemoryAvailable(args.pixels_size)) { 2263 if (!memory_type_tracker_->EnsureGPUMemoryAvailable(args.pixels_size)) {
2225 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name, 2264 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name,
2226 "out of memory"); 2265 "out of memory");
2227 return false; 2266 return false;
2228 } 2267 }
2229 2268
2230 // Write the TextureReference since this is valid. 2269 // Write the TextureReference since this is valid.
2231 *texture_ref = local_texture_ref; 2270 *texture_ref = local_texture_ref;
2232 return true; 2271 return true;
2233 } 2272 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY, 2317 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY,
2279 function_name, "out of memory"); 2318 function_name, "out of memory");
2280 return; 2319 return;
2281 } 2320 }
2282 DoTexImageArguments new_args = args; 2321 DoTexImageArguments new_args = args;
2283 scoped_ptr<char[]> zero(new char[args.pixels_size]); 2322 scoped_ptr<char[]> zero(new char[args.pixels_size]);
2284 memset(zero.get(), 0, args.pixels_size); 2323 memset(zero.get(), 0, args.pixels_size);
2285 for (GLenum face : undefined_faces) { 2324 for (GLenum face : undefined_faces) {
2286 new_args.target = face; 2325 new_args.target = face;
2287 new_args.pixels = zero.get(); 2326 new_args.pixels = zero.get();
2288 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 2327 DoTexImage(texture_state, state, framebuffer_state,
2289 function_name, texture_ref, new_args); 2328 function_name, texture_ref, new_args);
2290 texture->MarkLevelAsInternalWorkaround(face, args.level); 2329 texture->MarkLevelAsInternalWorkaround(face, args.level);
2291 } 2330 }
2292 } 2331 }
2293 2332
2294 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 2333 DoTexImage(texture_state, state, framebuffer_state,
2295 function_name, texture_ref, args); 2334 function_name, texture_ref, args);
2296 } 2335 }
2297 2336
2298 bool TextureManager::ValidateTexSubImage(ContextState* state, 2337 bool TextureManager::ValidateTexSubImage(ContextState* state,
2299 const char* function_name, 2338 const char* function_name,
2300 const DoTexSubImageArguments& args, 2339 const DoTexSubImageArguments& args,
2301 TextureRef** texture_ref) { 2340 TextureRef** texture_ref) {
2302 ErrorState* error_state = state->GetErrorState(); 2341 ErrorState* error_state = state->GetErrorState();
2303 const Validators* validators = feature_info_->validators(); 2342 const Validators* validators = feature_info_->validators();
2304 2343
2305 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D && 2344 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
2306 !validators->texture_target.IsValid(args.target)) || 2345 !validators->texture_target.IsValid(args.target)) ||
2307 (args.command_type == DoTexSubImageArguments::kTexSubImage3D && 2346 (args.command_type == DoTexSubImageArguments::kTexSubImage3D &&
2308 !validators->texture_3_d_target.IsValid(args.target))) { 2347 !validators->texture_3_d_target.IsValid(args.target))) {
2309 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, 2348 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
2310 args.target, "target"); 2349 args.target, "target");
2311 return false; 2350 return false;
2312 } 2351 }
2313 if (args.width < 0) { 2352 DCHECK(args.width >= 0 && args.height >= 0 && args.depth >= 0);
2314 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2315 "width < 0");
2316 return false;
2317 }
2318 if (args.height < 0) {
2319 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2320 "height < 0");
2321 return false;
2322 }
2323 if (args.depth < 0) {
2324 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2325 "depth < 0");
2326 return false;
2327 }
2328 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target); 2353 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target);
2329 if (!local_texture_ref) { 2354 if (!local_texture_ref) {
2330 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, 2355 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2331 "unknown texture for target"); 2356 "unknown texture for target");
2332 return false; 2357 return false;
2333 } 2358 }
2334 Texture* texture = local_texture_ref->texture(); 2359 Texture* texture = local_texture_ref->texture();
2335 GLenum current_type = 0; 2360 GLenum current_type = 0;
2336 GLenum internal_format = 0; 2361 GLenum internal_format = 0;
2337 if (!texture->GetLevelType(args.target, args.level, &current_type, 2362 if (!texture->GetLevelType(args.target, args.level, &current_type,
(...skipping 21 matching lines...) Expand all
2359 return false; 2384 return false;
2360 } 2385 }
2361 if ((GLES2Util::GetChannelsForFormat(args.format) & 2386 if ((GLES2Util::GetChannelsForFormat(args.format) &
2362 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && 2387 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 &&
2363 !feature_info_->IsES3Enabled()) { 2388 !feature_info_->IsES3Enabled()) {
2364 ERRORSTATE_SET_GL_ERROR( 2389 ERRORSTATE_SET_GL_ERROR(
2365 error_state, GL_INVALID_OPERATION, function_name, 2390 error_state, GL_INVALID_OPERATION, function_name,
2366 "can not supply data for depth or stencil textures"); 2391 "can not supply data for depth or stencil textures");
2367 return false; 2392 return false;
2368 } 2393 }
2369 DCHECK(args.pixels); 2394
2395 Buffer* buffer = state->bound_pixel_unpack_buffer.get();
2396 if (buffer) {
2397 if (buffer->GetMappedRange()) {
2398 ERRORSTATE_SET_GL_ERROR(
2399 error_state, GL_INVALID_OPERATION, function_name,
2400 "pixel unpack buffer should not be mapped to client memory");
2401 return error::kNoError;
2402 }
2403 base::CheckedNumeric<uint32_t> size = args.pixels_size;
2404 GLuint offset = ToGLuint(args.pixels);
2405 size += offset;
2406 if (!size.IsValid()) {
2407 ERRORSTATE_SET_GL_ERROR(
2408 error_state, GL_INVALID_VALUE, function_name,
2409 "size + offset overflow");
2410 return error::kNoError;
2411 }
2412 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2413 if (buffer_size < size.ValueOrDefault(0)) {
2414 ERRORSTATE_SET_GL_ERROR(
2415 error_state, GL_INVALID_OPERATION, function_name,
2416 "pixel unpack buffer is not large enough");
2417 return error::kNoError;
2418 }
2419 size_t type_size = GLES2Util::GetGLTypeSizeForTextures(args.type);
2420 DCHECK_LT(0u, type_size);
2421 if (offset % type_size != 0) {
2422 ERRORSTATE_SET_GL_ERROR(
2423 error_state, GL_INVALID_OPERATION, function_name,
2424 "offset is not evenly divisible by elements");
2425 return error::kNoError;
2426 }
2427 }
2370 *texture_ref = local_texture_ref; 2428 *texture_ref = local_texture_ref;
2371 return true; 2429 return true;
2372 } 2430 }
2373 2431
2374 void TextureManager::ValidateAndDoTexSubImage( 2432 void TextureManager::ValidateAndDoTexSubImage(
2375 GLES2Decoder* decoder, 2433 GLES2Decoder* decoder,
2376 DecoderTextureState* texture_state, 2434 DecoderTextureState* texture_state,
2377 ContextState* state, 2435 ContextState* state,
2378 DecoderFramebufferState* framebuffer_state, 2436 DecoderFramebufferState* framebuffer_state,
2379 const char* function_name, 2437 const char* function_name,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 const Texture::CompatibilitySwizzle* swizzle = 2540 const Texture::CompatibilitySwizzle* swizzle =
2483 GetCompatibilitySwizzle(format); 2541 GetCompatibilitySwizzle(format);
2484 if (swizzle) 2542 if (swizzle)
2485 return swizzle->dest_format; 2543 return swizzle->dest_format;
2486 } 2544 }
2487 return format; 2545 return format;
2488 } 2546 }
2489 2547
2490 void TextureManager::DoTexImage( 2548 void TextureManager::DoTexImage(
2491 DecoderTextureState* texture_state, 2549 DecoderTextureState* texture_state,
2492 ErrorState* error_state, 2550 ContextState* state,
2493 DecoderFramebufferState* framebuffer_state, 2551 DecoderFramebufferState* framebuffer_state,
2494 const char* function_name, 2552 const char* function_name,
2495 TextureRef* texture_ref, 2553 TextureRef* texture_ref,
2496 const DoTexImageArguments& args) { 2554 const DoTexImageArguments& args) {
2555 ErrorState* error_state = state->GetErrorState();
2497 Texture* texture = texture_ref->texture(); 2556 Texture* texture = texture_ref->texture();
2498 GLsizei tex_width = 0; 2557 GLsizei tex_width = 0;
2499 GLsizei tex_height = 0; 2558 GLsizei tex_height = 0;
2500 GLsizei tex_depth = 0; 2559 GLsizei tex_depth = 0;
2501 GLenum tex_type = 0; 2560 GLenum tex_type = 0;
2502 GLenum tex_internal_format = 0; 2561 GLenum tex_internal_format = 0;
2503 bool level_is_same = 2562 bool level_is_same =
2504 texture->GetLevelSize( 2563 texture->GetLevelSize(
2505 args.target, args.level, &tex_width, &tex_height, &tex_depth) && 2564 args.target, args.level, &tex_width, &tex_height, &tex_depth) &&
2506 args.width == tex_width && args.height == tex_height && 2565 args.width == tex_width && args.height == tex_height &&
2507 args.depth == tex_depth && 2566 args.depth == tex_depth &&
2508 texture->GetLevelType( 2567 texture->GetLevelType(
2509 args.target, args.level, &tex_type, &tex_internal_format) && 2568 args.target, args.level, &tex_type, &tex_internal_format) &&
2510 args.type == tex_type && args.internal_format == tex_internal_format; 2569 args.type == tex_type && args.internal_format == tex_internal_format;
2511 2570
2512 if (level_is_same && !args.pixels) { 2571 bool unpack_buffer_bound =
2572 (state->bound_pixel_unpack_buffer.get() != nullptr);
2573
2574 if (level_is_same && !args.pixels && !unpack_buffer_bound) {
2513 // Just set the level texture but mark the texture as uncleared. 2575 // Just set the level texture but mark the texture as uncleared.
2514 SetLevelInfo( 2576 SetLevelInfo(
2515 texture_ref, args.target, args.level, args.internal_format, args.width, 2577 texture_ref, args.target, args.level, args.internal_format, args.width,
2516 args.height, args.depth, args.border, args.format, args.type, 2578 args.height, args.depth, args.border, args.format, args.type,
2517 gfx::Rect()); 2579 gfx::Rect());
2518 texture_state->tex_image_failed = false; 2580 texture_state->tex_image_failed = false;
2519 return; 2581 return;
2520 } 2582 }
2521 2583
2522 if (texture->IsAttachedToFramebuffer()) { 2584 if (texture->IsAttachedToFramebuffer()) {
2523 framebuffer_state->clear_state_dirty = true; 2585 framebuffer_state->clear_state_dirty = true;
2524 } 2586 }
2525 2587
2526 if (texture_state->texsubimage_faster_than_teximage && 2588 if (texture_state->texsubimage_faster_than_teximage &&
2527 level_is_same && args.pixels) { 2589 level_is_same && args.pixels && !unpack_buffer_bound) {
2528 { 2590 {
2529 ScopedTextureUploadTimer timer(texture_state); 2591 ScopedTextureUploadTimer timer(texture_state);
2530 if (args.command_type == DoTexImageArguments::kTexImage3D) { 2592 if (args.command_type == DoTexImageArguments::kTexImage3D) {
2531 glTexSubImage3D(args.target, args.level, 0, 0, 0, 2593 glTexSubImage3D(args.target, args.level, 0, 0, 0,
2532 args.width, args.height, args.depth, 2594 args.width, args.height, args.depth,
2533 args.format, args.type, args.pixels); 2595 args.format, args.type, args.pixels);
2534 } else { 2596 } else {
2535 glTexSubImage2D(args.target, args.level, 0, 0, args.width, args.height, 2597 glTexSubImage2D(args.target, args.level, 0, 0, args.width, args.height,
2536 AdjustTexFormat(args.format), args.type, args.pixels); 2598 AdjustTexFormat(args.format), args.type, args.pixels);
2537 } 2599 }
(...skipping 21 matching lines...) Expand all
2559 } 2621 }
2560 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name); 2622 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name);
2561 if (args.command_type == DoTexImageArguments::kTexImage3D) { 2623 if (args.command_type == DoTexImageArguments::kTexImage3D) {
2562 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error, 2624 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error,
2563 GetAllGLErrors()); 2625 GetAllGLErrors());
2564 } else { 2626 } else {
2565 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error, 2627 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error,
2566 GetAllGLErrors()); 2628 GetAllGLErrors());
2567 } 2629 }
2568 if (error == GL_NO_ERROR) { 2630 if (error == GL_NO_ERROR) {
2569 bool set_as_cleared = (args.pixels != nullptr); 2631 bool set_as_cleared = (args.pixels != nullptr || unpack_buffer_bound);
2570 SetLevelInfo( 2632 SetLevelInfo(
2571 texture_ref, args.target, args.level, args.internal_format, args.width, 2633 texture_ref, args.target, args.level, args.internal_format, args.width,
2572 args.height, args.depth, args.border, args.format, args.type, 2634 args.height, args.depth, args.border, args.format, args.type,
2573 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect()); 2635 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect());
2574 texture->ApplyFormatWorkarounds(feature_info_.get()); 2636 texture->ApplyFormatWorkarounds(feature_info_.get());
2575 texture_state->tex_image_failed = false; 2637 texture_state->tex_image_failed = false;
2576 } 2638 }
2577 } 2639 }
2578 2640
2579 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1, 2641 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1,
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 uint32_t TextureManager::GetServiceIdGeneration() const { 2996 uint32_t TextureManager::GetServiceIdGeneration() const {
2935 return current_service_id_generation_; 2997 return current_service_id_generation_;
2936 } 2998 }
2937 2999
2938 void TextureManager::IncrementServiceIdGeneration() { 3000 void TextureManager::IncrementServiceIdGeneration() {
2939 current_service_id_generation_++; 3001 current_service_id_generation_++;
2940 } 3002 }
2941 3003
2942 } // namespace gles2 3004 } // namespace gles2
2943 } // namespace gpu 3005 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698