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

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

Issue 1426903002: gpu: Make glTexSubImage2D work with GL_SRGB_ALPHA on OpenGL (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove an unneeded hunk now that workarounds are used Created 5 years, 1 month 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 <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bits.h" 11 #include "base/bits.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
15 #include "base/trace_event/memory_dump_manager.h" 15 #include "base/trace_event/memory_dump_manager.h"
16 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 16 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
17 #include "gpu/command_buffer/service/context_state.h" 17 #include "gpu/command_buffer/service/context_state.h"
18 #include "gpu/command_buffer/service/error_state.h" 18 #include "gpu/command_buffer/service/error_state.h"
19 #include "gpu/command_buffer/service/feature_info.h" 19 #include "gpu/command_buffer/service/feature_info.h"
20 #include "gpu/command_buffer/service/framebuffer_manager.h" 20 #include "gpu/command_buffer/service/framebuffer_manager.h"
21 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 21 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
22 #include "gpu/command_buffer/service/mailbox_manager.h" 22 #include "gpu/command_buffer/service/mailbox_manager.h"
23 #include "gpu/command_buffer/service/memory_tracking.h" 23 #include "gpu/command_buffer/service/memory_tracking.h"
24 #include "ui/gl/gl_implementation.h" 24 #include "ui/gl/gl_implementation.h"
25 #include "ui/gl/gl_version_info.h"
25 #include "ui/gl/trace_util.h" 26 #include "ui/gl/trace_util.h"
26 27
27 namespace gpu { 28 namespace gpu {
28 namespace gles2 { 29 namespace gles2 {
29 30
30 namespace { 31 namespace {
31 32
32 // This should contain everything to uniquely identify a Texture. 33 // This should contain everything to uniquely identify a Texture.
33 const char TextureTag[] = "|Texture|"; 34 const char TextureTag[] = "|Texture|";
34 struct TextureSignature { 35 struct TextureSignature {
(...skipping 1960 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 1996 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state,
1996 function_name, texture_ref, new_args); 1997 function_name, texture_ref, new_args);
1997 } 1998 }
1998 return; 1999 return;
1999 } 2000 }
2000 2001
2001 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state, 2002 DoTexImage(texture_state, state->GetErrorState(), framebuffer_state,
2002 function_name, texture_ref, args); 2003 function_name, texture_ref, args);
2003 } 2004 }
2004 2005
2006 bool TextureManager::ValidateTexSubImage(ContextState* state,
2007 const char* function_name,
2008 const DoTexSubImageArguments& args,
2009 TextureRef** texture_ref) {
2010 ErrorState* error_state = state->GetErrorState();
2011 const Validators* validators = feature_info_->validators();
2012
2013 if (!validators->texture_target.IsValid(args.target)) {
2014 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
2015 args.target, "target");
2016 return false;
2017 }
2018 if (args.width < 0) {
2019 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2020 "width < 0");
2021 return false;
2022 }
2023 if (args.height < 0) {
2024 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2025 "height < 0");
2026 return false;
2027 }
2028 TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target);
2029 if (!local_texture_ref) {
2030 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2031 "unknown texture for target");
2032 return false;
2033 }
2034 Texture* texture = local_texture_ref->texture();
2035 GLenum current_type = 0;
2036 GLenum internal_format = 0;
2037 if (!texture->GetLevelType(args.target, args.level, &current_type,
2038 &internal_format)) {
2039 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2040 "level does not exist.");
2041 return false;
2042 }
2043 if (!ValidateTextureParameters(error_state, function_name, args.format,
2044 args.type, internal_format, args.level)) {
2045 return false;
2046 }
2047 if (args.type != current_type && !feature_info_->IsES3Enabled()) {
2048 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
2049 "type does not match type of texture.");
2050 return false;
2051 }
2052 if (!texture->ValidForTexture(args.target, args.level, args.xoffset,
2053 args.yoffset, 0, args.width, args.height, 1)) {
2054 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
2055 "bad dimensions.");
2056 return false;
2057 }
2058 if ((GLES2Util::GetChannelsForFormat(args.format) &
2059 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 &&
2060 !feature_info_->IsES3Enabled()) {
2061 ERRORSTATE_SET_GL_ERROR(
2062 error_state, GL_INVALID_OPERATION, function_name,
2063 "can not supply data for depth or stencil textures");
2064 return false;
2065 }
2066 DCHECK(args.pixels);
2067 *texture_ref = local_texture_ref;
2068 return true;
2069 }
2070
2071 void TextureManager::ValidateAndDoTexSubImage(
2072 GLES2Decoder* decoder,
2073 DecoderTextureState* texture_state,
2074 ContextState* state,
2075 DecoderFramebufferState* framebuffer_state,
2076 const char* function_name,
2077 const DoTexSubImageArguments& args) {
2078 ErrorState* error_state = state->GetErrorState();
2079 TextureRef* texture_ref;
2080 if (!ValidateTexSubImage(state, function_name, args, &texture_ref)) {
2081 return;
2082 }
2083
2084 Texture* texture = texture_ref->texture();
2085 GLsizei tex_width = 0;
2086 GLsizei tex_height = 0;
2087 bool ok = texture->GetLevelSize(args.target, args.level, &tex_width,
2088 &tex_height, nullptr);
2089 DCHECK(ok);
2090 if (args.xoffset != 0 || args.yoffset != 0 || args.width != tex_width ||
2091 args.height != tex_height) {
2092 gfx::Rect cleared_rect;
2093 if (CombineAdjacentRects(
2094 texture->GetLevelClearedRect(args.target, args.level),
2095 gfx::Rect(args.xoffset, args.yoffset, args.width, args.height),
2096 &cleared_rect)) {
2097 DCHECK_GE(cleared_rect.size().GetArea(),
2098 texture->GetLevelClearedRect(args.target, args.level)
2099 .size()
2100 .GetArea());
2101 SetLevelClearedRect(texture_ref, args.target, args.level, cleared_rect);
2102 } else {
2103 // Otherwise clear part of texture level that is not already cleared.
2104 if (!ClearTextureLevel(decoder, texture_ref, args.target, args.level)) {
2105 ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY,
2106 "glTexSubImage2D", "dimensions too big");
2107 return;
2108 }
2109 }
2110 ScopedTextureUploadTimer timer(texture_state);
2111 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset,
2112 args.width, args.height, AdjustTexFormat(args.format),
2113 args.type, args.pixels);
2114 return;
2115 }
2116
2117 if (!texture_state->texsubimage_faster_than_teximage &&
2118 !texture->IsImmutable() && !texture->HasImages()) {
2119 ScopedTextureUploadTimer timer(texture_state);
2120 GLenum internal_format;
2121 GLenum tex_type;
2122 texture->GetLevelType(args.target, args.level, &tex_type, &internal_format);
2123 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
2124 // to look it up.
2125 glTexImage2D(args.target, args.level, internal_format, args.width,
2126 args.height, 0, AdjustTexFormat(args.format), args.type,
2127 args.pixels);
2128 } else {
2129 ScopedTextureUploadTimer timer(texture_state);
2130 glTexSubImage2D(args.target, args.level, args.xoffset, args.yoffset,
2131 args.width, args.height, AdjustTexFormat(args.format),
2132 args.type, args.pixels);
2133 }
2134 SetLevelCleared(texture_ref, args.target, args.level, true);
2135 return;
2136 }
2137
2005 GLenum TextureManager::AdjustTexFormat(GLenum format) const { 2138 GLenum TextureManager::AdjustTexFormat(GLenum format) const {
2006 // TODO(bajones): GLES 3 allows for internal format and format to differ. 2139 // TODO(bajones): GLES 3 allows for internal format and format to differ.
2007 // This logic may need to change as a result. 2140 // This logic may need to change as a result.
2008 if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) { 2141 if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
2009 if (format == GL_SRGB_EXT) 2142 if (format == GL_SRGB_EXT)
2010 return GL_RGB; 2143 return GL_RGB;
2011 if (format == GL_SRGB_ALPHA_EXT) 2144 if (format == GL_SRGB_ALPHA_EXT)
2012 return GL_RGBA; 2145 return GL_RGBA;
2013 } 2146 }
2014 return format; 2147 return format;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name); 2215 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, function_name);
2083 if (error == GL_NO_ERROR) { 2216 if (error == GL_NO_ERROR) {
2084 SetLevelInfo( 2217 SetLevelInfo(
2085 texture_ref, args.target, args.level, args.internal_format, args.width, 2218 texture_ref, args.target, args.level, args.internal_format, args.width,
2086 args.height, args.depth, args.border, args.format, args.type, 2219 args.height, args.depth, args.border, args.format, args.type,
2087 args.pixels != NULL ? gfx::Rect(args.width, args.height) : gfx::Rect()); 2220 args.pixels != NULL ? gfx::Rect(args.width, args.height) : gfx::Rect());
2088 texture_state->tex_image_failed = false; 2221 texture_state->tex_image_failed = false;
2089 } 2222 }
2090 } 2223 }
2091 2224
2225 bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1,
2226 const gfx::Rect& rect2,
2227 gfx::Rect* result) {
2228 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|.
2229 if (rect1.IsEmpty() || rect2.Contains(rect1)) {
2230 *result = rect2;
2231 return true;
2232 }
2233
2234 // Return |rect1| if |rect2| is empty or |rect1| contains |rect2|.
2235 if (rect2.IsEmpty() || rect1.Contains(rect2)) {
2236 *result = rect1;
2237 return true;
2238 }
2239
2240 // Return the union of |rect1| and |rect2| if they share an edge.
2241 if (rect1.SharesEdgeWith(rect2)) {
2242 *result = gfx::UnionRects(rect1, rect2);
2243 return true;
2244 }
2245
2246 // Return false if it's not possible to combine |rect1| and |rect2|.
2247 return false;
2248 }
2249
2092 ScopedTextureUploadTimer::ScopedTextureUploadTimer( 2250 ScopedTextureUploadTimer::ScopedTextureUploadTimer(
2093 DecoderTextureState* texture_state) 2251 DecoderTextureState* texture_state)
2094 : texture_state_(texture_state), 2252 : texture_state_(texture_state),
2095 begin_time_(base::TimeTicks::Now()) { 2253 begin_time_(base::TimeTicks::Now()) {
2096 } 2254 }
2097 2255
2098 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { 2256 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
2099 texture_state_->texture_upload_count++; 2257 texture_state_->texture_upload_count++;
2100 texture_state_->total_texture_upload_time += 2258 texture_state_->total_texture_upload_time +=
2101 base::TimeTicks::Now() - begin_time_; 2259 base::TimeTicks::Now() - begin_time_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 pmd->AddOwnershipEdge(client_guid, service_guid, importance); 2318 pmd->AddOwnershipEdge(client_guid, service_guid, importance);
2161 2319
2162 // Dump all sub-levels held by the texture. They will appear below the main 2320 // Dump all sub-levels held by the texture. They will appear below the main
2163 // gl/textures/client_X/texture_Y dump. 2321 // gl/textures/client_X/texture_Y dump.
2164 ref->texture()->DumpLevelMemory(pmd, memory_tracker_->ClientTracingId(), 2322 ref->texture()->DumpLevelMemory(pmd, memory_tracker_->ClientTracingId(),
2165 dump_name); 2323 dump_name);
2166 } 2324 }
2167 2325
2168 } // namespace gles2 2326 } // namespace gles2
2169 } // namespace gpu 2327 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | gpu/command_buffer/tests/gl_ext_srgb_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698