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

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: 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
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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 (lhs.format == rhs.format) && 256 (lhs.format == rhs.format) &&
257 (lhs.type < rhs.type))); 257 (lhs.type < rhs.type)));
258 } 258 }
259 }; 259 };
260 260
261 // This class needs to be thread safe, so once supported_combinations_ 261 // This class needs to be thread safe, so once supported_combinations_
262 // are initialized in the constructor, it should never be modified later. 262 // are initialized in the constructor, it should never be modified later.
263 std::set<FormatType, FormatTypeCompare> supported_combinations_; 263 std::set<FormatType, FormatTypeCompare> supported_combinations_;
264 }; 264 };
265 265
266 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint.
267 GLuint ToGLuint(const void* ptr) {
268 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
269 }
270
266 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator = 271 base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator =
267 LAZY_INSTANCE_INITIALIZER; 272 LAZY_INSTANCE_INITIALIZER;
268 273
269 } // namespace anonymous 274 } // namespace anonymous
270 275
271 TextureManager::DestructionObserver::DestructionObserver() {} 276 TextureManager::DestructionObserver::DestructionObserver() {}
272 277
273 TextureManager::DestructionObserver::~DestructionObserver() {} 278 TextureManager::DestructionObserver::~DestructionObserver() {}
274 279
275 TextureManager::~TextureManager() { 280 TextureManager::~TextureManager() {
(...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 "unknown texture for target"); 2112 "unknown texture for target");
2108 return false; 2113 return false;
2109 } 2114 }
2110 if (local_texture_ref->texture()->IsImmutable()) { 2115 if (local_texture_ref->texture()->IsImmutable()) {
2111 ERRORSTATE_SET_GL_ERROR( 2116 ERRORSTATE_SET_GL_ERROR(
2112 error_state, GL_INVALID_OPERATION, function_name, 2117 error_state, GL_INVALID_OPERATION, function_name,
2113 "texture is immutable"); 2118 "texture is immutable");
2114 return false; 2119 return false;
2115 } 2120 }
2116 2121
2122 Buffer* buffer = state->bound_pixel_unpack_buffer.get();
2123 if (buffer) {
2124 if (buffer->GetMappedRange()) {
2125 ERRORSTATE_SET_GL_ERROR(
2126 error_state, GL_INVALID_OPERATION, function_name,
2127 "pixel unpack buffer should not be mapped to client memory");
2128 return error::kNoError;
2129 }
2130 base::CheckedNumeric<uint32_t> size = args.pixels_size;
2131 size += ToGLuint(args.pixels);
2132 if (!size.IsValid()) {
2133 ERRORSTATE_SET_GL_ERROR(
2134 error_state, GL_INVALID_VALUE, function_name,
2135 "size + offset overflow");
2136 return error::kNoError;
2137 }
2138 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2139 if (buffer_size < size.ValueOrDefault(0)) {
2140 ERRORSTATE_SET_GL_ERROR(
2141 error_state, GL_INVALID_OPERATION, function_name,
2142 "pixel unpack buffer is not large enough");
2143 return error::kNoError;
2144 }
2145 size_t type_size = GLES2Util::GetGLTypeSizeForTextures(args.type);
2146 DCHECK_LT(0u, type_size);
2147 if (buffer_size % type_size != 0) {
piman 2016/03/08 01:56:50 Why this check? The buffer size doesn't matter, as
Zhenyao Mo 2016/03/09 18:41:05 See ES Spec 3.0.4 page 113, under $3.7 -> Unpackin
piman 2016/03/09 18:52:05 I still don't get it. The 2 requirements are: 1- t
2148 ERRORSTATE_SET_GL_ERROR(
2149 error_state, GL_INVALID_OPERATION, function_name,
2150 "buffer size is not evenly divisible by elements");
2151 return error::kNoError;
2152 }
2153 }
2154
2117 if (!memory_type_tracker_->EnsureGPUMemoryAvailable(args.pixels_size)) { 2155 if (!memory_type_tracker_->EnsureGPUMemoryAvailable(args.pixels_size)) {
2118 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name, 2156 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name,
2119 "out of memory"); 2157 "out of memory");
2120 return false; 2158 return false;
2121 } 2159 }
2122 2160
2123 // Write the TextureReference since this is valid. 2161 // Write the TextureReference since this is valid.
2124 *texture_ref = local_texture_ref; 2162 *texture_ref = local_texture_ref;
2125 return true; 2163 return true;
2126 } 2164 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2171 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY, 2209 ERRORSTATE_SET_GL_ERROR(state->GetErrorState(), GL_OUT_OF_MEMORY,
2172 function_name, "out of memory"); 2210 function_name, "out of memory");
2173 return; 2211 return;
2174 } 2212 }
2175 DoTexImageArguments new_args = args; 2213 DoTexImageArguments new_args = args;
2176 scoped_ptr<char[]> zero(new char[args.pixels_size]); 2214 scoped_ptr<char[]> zero(new char[args.pixels_size]);
2177 memset(zero.get(), 0, args.pixels_size); 2215 memset(zero.get(), 0, args.pixels_size);
2178 for (GLenum face : undefined_faces) { 2216 for (GLenum face : undefined_faces) {
2179 new_args.target = face; 2217 new_args.target = face;
2180 new_args.pixels = zero.get(); 2218 new_args.pixels = zero.get();
2181 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 2219 DoTexImage(texture_state, state, framebuffer_state,
2182 function_name, texture_ref, new_args); 2220 function_name, texture_ref, new_args);
2183 texture->MarkLevelAsInternalWorkaround(face, args.level); 2221 texture->MarkLevelAsInternalWorkaround(face, args.level);
2184 } 2222 }
2185 } 2223 }
2186 2224
2187 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 2225 DoTexImage(texture_state, state, framebuffer_state,
2188 function_name, texture_ref, args); 2226 function_name, texture_ref, args);
2189 } 2227 }
2190 2228
2191 bool TextureManager::ValidateTexSubImage(ContextState* state, 2229 bool TextureManager::ValidateTexSubImage(ContextState* state,
2192 const char* function_name, 2230 const char* function_name,
2193 const DoTexSubImageArguments& args, 2231 const DoTexSubImageArguments& args,
2194 TextureRef** texture_ref) { 2232 TextureRef** texture_ref) {
2195 ErrorState* error_state = state->GetErrorState(); 2233 ErrorState* error_state = state->GetErrorState();
2196 const Validators* validators = feature_info_->validators(); 2234 const Validators* validators = feature_info_->validators();
2197 2235
2198 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D && 2236 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
2199 !validators->texture_target.IsValid(args.target)) || 2237 !validators->texture_target.IsValid(args.target)) ||
2200 (args.command_type == DoTexSubImageArguments::kTexSubImage3D && 2238 (args.command_type == DoTexSubImageArguments::kTexSubImage3D &&
2201 !validators->texture_3_d_target.IsValid(args.target))) { 2239 !validators->texture_3_d_target.IsValid(args.target))) {
2202 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, 2240 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
2203 args.target, "target"); 2241 args.target, "target");
2204 return false; 2242 return false;
2205 } 2243 }
2206 if (args.width < 0) { 2244 DCHECK(args.width >= 0 && args.height >= 0 && args.depth >= 0);
2207 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2208 "width < 0");
2209 return false;
2210 }
2211 if (args.height < 0) {
2212 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2213 "height < 0");
2214 return false;
2215 }
2216 if (args.depth < 0) {
2217 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2218 "depth < 0");
2219 return false;
2220 }
2221 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target); 2245 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target);
2222 if (!local_texture_ref) { 2246 if (!local_texture_ref) {
2223 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, 2247 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2224 "unknown texture for target"); 2248 "unknown texture for target");
2225 return false; 2249 return false;
2226 } 2250 }
2227 Texture* texture = local_texture_ref->texture(); 2251 Texture* texture = local_texture_ref->texture();
2228 GLenum current_type = 0; 2252 GLenum current_type = 0;
2229 GLenum internal_format = 0; 2253 GLenum internal_format = 0;
2230 if (!texture->GetLevelType(args.target, args.level, &current_type, 2254 if (!texture->GetLevelType(args.target, args.level, &current_type,
(...skipping 21 matching lines...) Expand all
2252 return false; 2276 return false;
2253 } 2277 }
2254 if ((GLES2Util::GetChannelsForFormat(args.format) & 2278 if ((GLES2Util::GetChannelsForFormat(args.format) &
2255 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && 2279 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 &&
2256 !feature_info_->IsES3Enabled()) { 2280 !feature_info_->IsES3Enabled()) {
2257 ERRORSTATE_SET_GL_ERROR( 2281 ERRORSTATE_SET_GL_ERROR(
2258 error_state, GL_INVALID_OPERATION, function_name, 2282 error_state, GL_INVALID_OPERATION, function_name,
2259 "can not supply data for depth or stencil textures"); 2283 "can not supply data for depth or stencil textures");
2260 return false; 2284 return false;
2261 } 2285 }
2262 DCHECK(args.pixels); 2286
2287 Buffer* buffer = state->bound_pixel_unpack_buffer.get();
2288 if (buffer) {
2289 if (buffer->GetMappedRange()) {
2290 ERRORSTATE_SET_GL_ERROR(
2291 error_state, GL_INVALID_OPERATION, function_name,
2292 "pixel unpack buffer should not be mapped to client memory");
2293 return error::kNoError;
2294 }
2295 base::CheckedNumeric<uint32_t> size = args.pixels_size;
2296 size += ToGLuint(args.pixels);
2297 if (!size.IsValid()) {
2298 ERRORSTATE_SET_GL_ERROR(
2299 error_state, GL_INVALID_VALUE, function_name,
2300 "size + offset overflow");
2301 return error::kNoError;
2302 }
2303 uint32_t buffer_size = static_cast<uint32_t>(buffer->size());
2304 if (buffer_size < size.ValueOrDefault(0)) {
2305 ERRORSTATE_SET_GL_ERROR(
2306 error_state, GL_INVALID_OPERATION, function_name,
2307 "pixel unpack buffer is not large enough");
2308 return error::kNoError;
2309 }
2310 size_t type_size = GLES2Util::GetGLTypeSizeForTextures(args.type);
2311 DCHECK_LT(0u, type_size);
2312 if (buffer_size % type_size != 0) {
piman 2016/03/08 01:56:50 Same here
Zhenyao Mo 2016/03/09 18:41:05 Same answer. It is specified in a difference plac
2313 ERRORSTATE_SET_GL_ERROR(
2314 error_state, GL_INVALID_OPERATION, function_name,
2315 "buffer size is not evenly divisible by elements");
2316 return error::kNoError;
2317 }
2318 }
2263 *texture_ref = local_texture_ref; 2319 *texture_ref = local_texture_ref;
2264 return true; 2320 return true;
2265 } 2321 }
2266 2322
2267 void TextureManager::ValidateAndDoTexSubImage( 2323 void TextureManager::ValidateAndDoTexSubImage(
2268 GLES2Decoder* decoder, 2324 GLES2Decoder* decoder,
2269 DecoderTextureState* texture_state, 2325 DecoderTextureState* texture_state,
2270 ContextState* state, 2326 ContextState* state,
2271 DecoderFramebufferState* framebuffer_state, 2327 DecoderFramebufferState* framebuffer_state,
2272 const char* function_name, 2328 const char* function_name,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 if (format == GL_SRGB_EXT) 2414 if (format == GL_SRGB_EXT)
2359 return GL_RGB; 2415 return GL_RGB;
2360 if (format == GL_SRGB_ALPHA_EXT) 2416 if (format == GL_SRGB_ALPHA_EXT)
2361 return GL_RGBA; 2417 return GL_RGBA;
2362 } 2418 }
2363 return format; 2419 return format;
2364 } 2420 }
2365 2421
2366 void TextureManager::DoTexImage( 2422 void TextureManager::DoTexImage(
2367 DecoderTextureState* texture_state, 2423 DecoderTextureState* texture_state,
2368 ErrorState* error_state, 2424 ContextState* state,
2369 DecoderFramebufferState* framebuffer_state, 2425 DecoderFramebufferState* framebuffer_state,
2370 const char* function_name, 2426 const char* function_name,
2371 TextureRef* texture_ref, 2427 TextureRef* texture_ref,
2372 const DoTexImageArguments& args) { 2428 const DoTexImageArguments& args) {
2429 ErrorState* error_state = state->GetErrorState();
2373 Texture* texture = texture_ref->texture(); 2430 Texture* texture = texture_ref->texture();
2374 GLsizei tex_width = 0; 2431 GLsizei tex_width = 0;
2375 GLsizei tex_height = 0; 2432 GLsizei tex_height = 0;
2376 GLsizei tex_depth = 0; 2433 GLsizei tex_depth = 0;
2377 GLenum tex_type = 0; 2434 GLenum tex_type = 0;
2378 GLenum tex_internal_format = 0; 2435 GLenum tex_internal_format = 0;
2379 bool level_is_same = 2436 bool level_is_same =
2380 texture->GetLevelSize( 2437 texture->GetLevelSize(
2381 args.target, args.level, &tex_width, &tex_height, &tex_depth) && 2438 args.target, args.level, &tex_width, &tex_height, &tex_depth) &&
2382 args.width == tex_width && args.height == tex_height && 2439 args.width == tex_width && args.height == tex_height &&
2383 args.depth == tex_depth && 2440 args.depth == tex_depth &&
2384 texture->GetLevelType( 2441 texture->GetLevelType(
2385 args.target, args.level, &tex_type, &tex_internal_format) && 2442 args.target, args.level, &tex_type, &tex_internal_format) &&
2386 args.type == tex_type && args.internal_format == tex_internal_format; 2443 args.type == tex_type && args.internal_format == tex_internal_format;
2387 2444
2388 if (level_is_same && !args.pixels) { 2445 bool unpack_buffer_bound =
2446 (state->bound_pixel_unpack_buffer.get() != nullptr);
2447
2448 if (level_is_same && !args.pixels && !unpack_buffer_bound) {
2389 // Just set the level texture but mark the texture as uncleared. 2449 // Just set the level texture but mark the texture as uncleared.
2390 SetLevelInfo( 2450 SetLevelInfo(
2391 texture_ref, args.target, args.level, args.internal_format, args.width, 2451 texture_ref, args.target, args.level, args.internal_format, args.width,
2392 args.height, args.depth, args.border, args.format, args.type, 2452 args.height, args.depth, args.border, args.format, args.type,
2393 gfx::Rect()); 2453 gfx::Rect());
2394 texture_state->tex_image_failed = false; 2454 texture_state->tex_image_failed = false;
2395 return; 2455 return;
2396 } 2456 }
2397 2457
2398 if (texture->IsAttachedToFramebuffer()) { 2458 if (texture->IsAttachedToFramebuffer()) {
2399 framebuffer_state->clear_state_dirty = true; 2459 framebuffer_state->clear_state_dirty = true;
2400 } 2460 }
2401 2461
2402 if (texture_state->texsubimage_faster_than_teximage && 2462 if (texture_state->texsubimage_faster_than_teximage &&
2403 level_is_same && args.pixels) { 2463 level_is_same && args.pixels && !unpack_buffer_bound) {
2404 { 2464 {
2405 ScopedTextureUploadTimer timer(texture_state); 2465 ScopedTextureUploadTimer timer(texture_state);
2406 if (args.command_type == DoTexImageArguments::kTexImage3D) { 2466 if (args.command_type == DoTexImageArguments::kTexImage3D) {
2407 glTexSubImage3D(args.target, args.level, 0, 0, 0, 2467 glTexSubImage3D(args.target, args.level, 0, 0, 0,
2408 args.width, args.height, args.depth, 2468 args.width, args.height, args.depth,
2409 args.format, args.type, args.pixels); 2469 args.format, args.type, args.pixels);
2410 } else { 2470 } else {
2411 glTexSubImage2D(args.target, args.level, 0, 0, args.width, args.height, 2471 glTexSubImage2D(args.target, args.level, 0, 0, args.width, args.height,
2412 AdjustTexFormat(args.format), args.type, args.pixels); 2472 AdjustTexFormat(args.format), args.type, args.pixels);
2413 } 2473 }
(...skipping 20 matching lines...) Expand all
2434 } 2494 }
2435 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name); 2495 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name);
2436 if (args.command_type == DoTexImageArguments::kTexImage3D) { 2496 if (args.command_type == DoTexImageArguments::kTexImage3D) {
2437 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error, 2497 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage3D", error,
2438 GetAllGLErrors()); 2498 GetAllGLErrors());
2439 } else { 2499 } else {
2440 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error, 2500 UMA_HISTOGRAM_CUSTOM_ENUMERATION("GPU.Error.TexImage2D", error,
2441 GetAllGLErrors()); 2501 GetAllGLErrors());
2442 } 2502 }
2443 if (error == GL_NO_ERROR) { 2503 if (error == GL_NO_ERROR) {
2444 bool set_as_cleared = (args.pixels != nullptr); 2504 bool set_as_cleared = (args.pixels != nullptr || unpack_buffer_bound);
2445 SetLevelInfo( 2505 SetLevelInfo(
2446 texture_ref, args.target, args.level, args.internal_format, args.width, 2506 texture_ref, args.target, args.level, args.internal_format, args.width,
2447 args.height, args.depth, args.border, args.format, args.type, 2507 args.height, args.depth, args.border, args.format, args.type,
2448 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect()); 2508 set_as_cleared ? gfx::Rect(args.width, args.height) : gfx::Rect());
2449 texture_state->tex_image_failed = false; 2509 texture_state->tex_image_failed = false;
2450 } 2510 }
2451 } 2511 }
2452 2512
2453 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1, 2513 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1,
2454 const gfx::Rect& rect2, 2514 const gfx::Rect& rect2,
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 uint32_t TextureManager::GetServiceIdGeneration() const { 2868 uint32_t TextureManager::GetServiceIdGeneration() const {
2809 return current_service_id_generation_; 2869 return current_service_id_generation_;
2810 } 2870 }
2811 2871
2812 void TextureManager::IncrementServiceIdGeneration() { 2872 void TextureManager::IncrementServiceIdGeneration() {
2813 current_service_id_generation_++; 2873 current_service_id_generation_++;
2814 } 2874 }
2815 2875
2816 } // namespace gles2 2876 } // namespace gles2
2817 } // namespace gpu 2877 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698