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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.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/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 183 }
184 184
185 struct Vec4f { 185 struct Vec4f {
186 explicit Vec4f(const Vec4& data) { 186 explicit Vec4f(const Vec4& data) {
187 data.GetValues(v); 187 data.GetValues(v);
188 } 188 }
189 189
190 GLfloat v[4]; 190 GLfloat v[4];
191 }; 191 };
192 192
193 // Returns the union of |rect1| and |rect2| if one of the rectangles is empty,
194 // contains the other rectangle or shares an edge with the other rectangle.
195 bool CombineAdjacentRects(const gfx::Rect& rect1,
196 const gfx::Rect& rect2,
197 gfx::Rect* result) {
198 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|.
199 if (rect1.IsEmpty() || rect2.Contains(rect1)) {
200 *result = rect2;
201 return true;
202 }
203
204 // Return |rect1| if |rect2| is empty or |rect1| contains |rect2|.
205 if (rect2.IsEmpty() || rect1.Contains(rect2)) {
206 *result = rect1;
207 return true;
208 }
209
210 // Return the union of |rect1| and |rect2| if they share an edge.
211 if (rect1.SharesEdgeWith(rect2)) {
212 *result = gfx::UnionRects(rect1, rect2);
213 return true;
214 }
215
216 // Return false if it's not possible to combine |rect1| and |rect2|.
217 return false;
218 }
219
220 GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { 193 GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
221 switch (internalformat) { 194 switch (internalformat) {
222 case GL_R8: 195 case GL_R8:
223 case GL_R8_SNORM: 196 case GL_R8_SNORM:
224 case GL_R16F: 197 case GL_R16F:
225 case GL_R32F: 198 case GL_R32F:
226 return GL_RED; 199 return GL_RED;
227 case GL_R8UI: 200 case GL_R8UI:
228 case GL_R8I: 201 case GL_R8I:
229 case GL_R16UI: 202 case GL_R16UI:
(...skipping 10872 matching lines...) Expand 10 before | Expand all | Expand 10 after
11102 GLint copyX = 0; 11075 GLint copyX = 0;
11103 GLint copyY = 0; 11076 GLint copyY = 0;
11104 GLint copyWidth = 0; 11077 GLint copyWidth = 0;
11105 GLint copyHeight = 0; 11078 GLint copyHeight = 0;
11106 Clip(x, width, size.width(), &copyX, &copyWidth); 11079 Clip(x, width, size.width(), &copyX, &copyWidth);
11107 Clip(y, height, size.height(), &copyY, &copyHeight); 11080 Clip(y, height, size.height(), &copyY, &copyHeight);
11108 11081
11109 if (xoffset != 0 || yoffset != 0 || width != size.width() || 11082 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
11110 height != size.height()) { 11083 height != size.height()) {
11111 gfx::Rect cleared_rect; 11084 gfx::Rect cleared_rect;
11112 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level), 11085 if (TextureManager::CombineAdjacentRects(
11113 gfx::Rect(xoffset, yoffset, width, height), 11086 texture->GetLevelClearedRect(target, level),
11114 &cleared_rect)) { 11087 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
11115 DCHECK_GE(cleared_rect.size().GetArea(), 11088 DCHECK_GE(cleared_rect.size().GetArea(),
11116 texture->GetLevelClearedRect(target, level).size().GetArea()); 11089 texture->GetLevelClearedRect(target, level).size().GetArea());
11117 texture_manager()->SetLevelClearedRect(texture_ref, target, level, 11090 texture_manager()->SetLevelClearedRect(texture_ref, target, level,
11118 cleared_rect); 11091 cleared_rect);
11119 } else { 11092 } else {
11120 // Otherwise clear part of texture level that is not already cleared. 11093 // Otherwise clear part of texture level that is not already cleared.
11121 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 11094 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
11122 level)) { 11095 level)) {
11123 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", 11096 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
11124 "dimensions too big"); 11097 "dimensions too big");
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
11158 glCopyTexSubImage2D(target, level, 11131 glCopyTexSubImage2D(target, level,
11159 destX, destY, copyX, copyY, 11132 destX, destY, copyX, copyY,
11160 copyWidth, copyHeight); 11133 copyWidth, copyHeight);
11161 } 11134 }
11162 11135
11163 // This may be a slow command. Exit command processing to allow for 11136 // This may be a slow command. Exit command processing to allow for
11164 // context preemption and GPU watchdog checks. 11137 // context preemption and GPU watchdog checks.
11165 ExitCommandProcessingEarly(); 11138 ExitCommandProcessingEarly();
11166 } 11139 }
11167 11140
11168 bool GLES2DecoderImpl::ValidateTexSubImage2D(
11169 error::Error* error,
11170 const char* function_name,
11171 GLenum target,
11172 GLint level,
11173 GLint xoffset,
11174 GLint yoffset,
11175 GLsizei width,
11176 GLsizei height,
11177 GLenum format,
11178 GLenum type,
11179 const void * data) {
11180 (*error) = error::kNoError;
11181 if (!validators_->texture_target.IsValid(target)) {
11182 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
11183 return false;
11184 }
11185 if (width < 0) {
11186 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
11187 return false;
11188 }
11189 if (height < 0) {
11190 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
11191 return false;
11192 }
11193 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11194 &state_, target);
11195 if (!texture_ref) {
11196 LOCAL_SET_GL_ERROR(
11197 GL_INVALID_OPERATION,
11198 function_name, "unknown texture for target");
11199 return false;
11200 }
11201 Texture* texture = texture_ref->texture();
11202 GLenum current_type = 0;
11203 GLenum internal_format = 0;
11204 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
11205 LOCAL_SET_GL_ERROR(
11206 GL_INVALID_OPERATION, function_name, "level does not exist.");
11207 return false;
11208 }
11209 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
11210 function_name, format, type, internal_format, level)) {
11211 return false;
11212 }
11213 if (type != current_type && !feature_info_->IsES3Enabled()) {
11214 LOCAL_SET_GL_ERROR(
11215 GL_INVALID_OPERATION,
11216 function_name, "type does not match type of texture.");
11217 return false;
11218 }
11219 if (!texture->ValidForTexture(
11220 target, level, xoffset, yoffset, 0, width, height, 1)) {
11221 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
11222 return false;
11223 }
11224 if ((GLES2Util::GetChannelsForFormat(format) &
11225 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0
11226 && !feature_info_->IsES3Enabled()) {
11227 LOCAL_SET_GL_ERROR(
11228 GL_INVALID_OPERATION,
11229 function_name, "can not supply data for depth or stencil textures");
11230 return false;
11231 }
11232 if (data == NULL) {
11233 (*error) = error::kOutOfBounds;
11234 return false;
11235 }
11236 return true;
11237 }
11238
11239 error::Error GLES2DecoderImpl::DoTexSubImage2D(
11240 GLenum target,
11241 GLint level,
11242 GLint xoffset,
11243 GLint yoffset,
11244 GLsizei width,
11245 GLsizei height,
11246 GLenum format,
11247 GLenum type,
11248 const void * data) {
11249 error::Error error = error::kNoError;
11250 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
11251 xoffset, yoffset, width, height, format, type, data)) {
11252 return error;
11253 }
11254 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11255 &state_, target);
11256 Texture* texture = texture_ref->texture();
11257 GLsizei tex_width = 0;
11258 GLsizei tex_height = 0;
11259 bool ok = texture->GetLevelSize(
11260 target, level, &tex_width, &tex_height, nullptr);
11261 DCHECK(ok);
11262 if (xoffset != 0 || yoffset != 0 ||
11263 width != tex_width || height != tex_height) {
11264 gfx::Rect cleared_rect;
11265 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level),
11266 gfx::Rect(xoffset, yoffset, width, height),
11267 &cleared_rect)) {
11268 DCHECK_GE(cleared_rect.size().GetArea(),
11269 texture->GetLevelClearedRect(target, level).size().GetArea());
11270 texture_manager()->SetLevelClearedRect(texture_ref, target, level,
11271 cleared_rect);
11272 } else {
11273 // Otherwise clear part of texture level that is not already cleared.
11274 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
11275 level)) {
11276 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexSubImage2D",
11277 "dimensions too big");
11278 return error::kNoError;
11279 }
11280 }
11281 ScopedTextureUploadTimer timer(&texture_state_);
11282 glTexSubImage2D(
11283 target, level, xoffset, yoffset, width, height, format, type, data);
11284 return error::kNoError;
11285 }
11286
11287 if (!texture_state_.texsubimage_faster_than_teximage &&
11288 !texture->IsImmutable() &&
11289 !texture->HasImages()) {
11290 ScopedTextureUploadTimer timer(&texture_state_);
11291 GLenum internal_format;
11292 GLenum tex_type;
11293 texture->GetLevelType(target, level, &tex_type, &internal_format);
11294 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
11295 // to look it up.
11296 glTexImage2D(
11297 target, level, internal_format, width, height, 0, format, type, data);
11298 } else {
11299 ScopedTextureUploadTimer timer(&texture_state_);
11300 glTexSubImage2D(
11301 target, level, xoffset, yoffset, width, height, format, type, data);
11302 }
11303 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
11304
11305 // This may be a slow command. Exit command processing to allow for
11306 // context preemption and GPU watchdog checks.
11307 ExitCommandProcessingEarly();
11308 return error::kNoError;
11309 }
11310
11311 error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size, 11141 error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
11312 const void* cmd_data) { 11142 const void* cmd_data) {
11313 const gles2::cmds::TexSubImage2D& c = 11143 const gles2::cmds::TexSubImage2D& c =
11314 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data); 11144 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
11315 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D", 11145 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
11316 "width", c.width, "height", c.height); 11146 "width", c.width, "height", c.height);
11317 GLboolean internal = static_cast<GLboolean>(c.internal); 11147 GLboolean internal = static_cast<GLboolean>(c.internal);
11318 if (internal == GL_TRUE && texture_state_.tex_image_failed) 11148 if (internal == GL_TRUE && texture_state_.tex_image_failed)
11319 return error::kNoError; 11149 return error::kNoError;
11320 11150
11321 GLenum target = static_cast<GLenum>(c.target); 11151 GLenum target = static_cast<GLenum>(c.target);
11322 GLint level = static_cast<GLint>(c.level); 11152 GLint level = static_cast<GLint>(c.level);
11323 GLint xoffset = static_cast<GLint>(c.xoffset); 11153 GLint xoffset = static_cast<GLint>(c.xoffset);
11324 GLint yoffset = static_cast<GLint>(c.yoffset); 11154 GLint yoffset = static_cast<GLint>(c.yoffset);
11325 GLsizei width = static_cast<GLsizei>(c.width); 11155 GLsizei width = static_cast<GLsizei>(c.width);
11326 GLsizei height = static_cast<GLsizei>(c.height); 11156 GLsizei height = static_cast<GLsizei>(c.height);
11327 GLenum format = static_cast<GLenum>(c.format); 11157 GLenum format = static_cast<GLenum>(c.format);
11328 GLenum type = static_cast<GLenum>(c.type); 11158 GLenum type = static_cast<GLenum>(c.type);
11329 uint32 data_size; 11159 uint32 data_size;
11330 if (!GLES2Util::ComputeImageDataSizes( 11160 if (!GLES2Util::ComputeImageDataSizes(
11331 width, height, 1, format, type, state_.unpack_alignment, &data_size, 11161 width, height, 1, format, type, state_.unpack_alignment, &data_size,
11332 NULL, NULL)) { 11162 NULL, NULL)) {
11333 return error::kOutOfBounds; 11163 return error::kOutOfBounds;
11334 } 11164 }
11165
11335 const void* pixels = GetSharedMemoryAs<const void*>( 11166 const void* pixels = GetSharedMemoryAs<const void*>(
11336 c.pixels_shm_id, c.pixels_shm_offset, data_size); 11167 c.pixels_shm_id, c.pixels_shm_offset, data_size);
11337 return DoTexSubImage2D( 11168 if (!pixels)
11338 target, level, xoffset, yoffset, width, height, format, type, pixels); 11169 return error::kOutOfBounds;
11170
11171 TextureManager::DoTexSubImageArguments args = {
11172 target, level, xoffset, yoffset, width,
11173 height, format, type, pixels, data_size};
11174 texture_manager()->ValidateAndDoTexSubImage(this, &texture_state_, &state_,
11175 &framebuffer_state_,
11176 "glTexSubImage2D", args);
11177
11178 // This may be a slow command. Exit command processing to allow for
11179 // context preemption and GPU watchdog checks.
11180 ExitCommandProcessingEarly();
11181 return error::kNoError;
11339 } 11182 }
11340 11183
11341 error::Error GLES2DecoderImpl::DoTexSubImage3D( 11184 error::Error GLES2DecoderImpl::DoTexSubImage3D(
11342 GLenum target, 11185 GLenum target,
11343 GLint level, 11186 GLint level,
11344 GLint xoffset, 11187 GLint xoffset,
11345 GLint yoffset, 11188 GLint yoffset,
11346 GLint zoffset, 11189 GLint zoffset,
11347 GLsizei width, 11190 GLsizei width,
11348 GLsizei height, 11191 GLsizei height,
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
13266 } 13109 }
13267 13110
13268 int dest_width = 0; 13111 int dest_width = 0;
13269 int dest_height = 0; 13112 int dest_height = 0;
13270 bool ok = dest_texture->GetLevelSize( 13113 bool ok = dest_texture->GetLevelSize(
13271 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); 13114 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
13272 DCHECK(ok); 13115 DCHECK(ok);
13273 if (xoffset != 0 || yoffset != 0 || width != dest_width || 13116 if (xoffset != 0 || yoffset != 0 || width != dest_width ||
13274 height != dest_height) { 13117 height != dest_height) {
13275 gfx::Rect cleared_rect; 13118 gfx::Rect cleared_rect;
13276 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0), 13119 if (TextureManager::CombineAdjacentRects(
13277 gfx::Rect(xoffset, yoffset, width, height), 13120 dest_texture->GetLevelClearedRect(target, 0),
13278 &cleared_rect)) { 13121 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
13279 DCHECK_GE(cleared_rect.size().GetArea(), 13122 DCHECK_GE(cleared_rect.size().GetArea(),
13280 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); 13123 dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
13281 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, 13124 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
13282 cleared_rect); 13125 cleared_rect);
13283 } else { 13126 } else {
13284 // Otherwise clear part of texture level that is not already cleared. 13127 // Otherwise clear part of texture level that is not already cleared.
13285 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, 13128 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
13286 0)) { 13129 0)) {
13287 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", 13130 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
13288 "destination texture dimensions too big"); 13131 "destination texture dimensions too big");
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
13604 } 13447 }
13605 13448
13606 int dest_width = 0; 13449 int dest_width = 0;
13607 int dest_height = 0; 13450 int dest_height = 0;
13608 bool ok = dest_texture->GetLevelSize( 13451 bool ok = dest_texture->GetLevelSize(
13609 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); 13452 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
13610 DCHECK(ok); 13453 DCHECK(ok);
13611 if (xoffset != 0 || yoffset != 0 || width != dest_width || 13454 if (xoffset != 0 || yoffset != 0 || width != dest_width ||
13612 height != dest_height) { 13455 height != dest_height) {
13613 gfx::Rect cleared_rect; 13456 gfx::Rect cleared_rect;
13614 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0), 13457 if (TextureManager::CombineAdjacentRects(
13615 gfx::Rect(xoffset, yoffset, width, height), 13458 dest_texture->GetLevelClearedRect(target, 0),
13616 &cleared_rect)) { 13459 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
13617 DCHECK_GE(cleared_rect.size().GetArea(), 13460 DCHECK_GE(cleared_rect.size().GetArea(),
13618 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); 13461 dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
13619 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, 13462 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
13620 cleared_rect); 13463 cleared_rect);
13621 } else { 13464 } else {
13622 // Otherwise clear part of texture level that is not already cleared. 13465 // Otherwise clear part of texture level that is not already cleared.
13623 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, 13466 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
13624 0)) { 13467 0)) {
13625 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, 13468 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY,
13626 "glCompressedCopySubTextureCHROMIUM", 13469 "glCompressedCopySubTextureCHROMIUM",
(...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after
15600 return error::kNoError; 15443 return error::kNoError;
15601 } 15444 }
15602 15445
15603 // Include the auto-generated part of this file. We split this because it means 15446 // Include the auto-generated part of this file. We split this because it means
15604 // we can easily edit the non-auto generated parts right here in this file 15447 // we can easily edit the non-auto generated parts right here in this file
15605 // instead of having to edit some template or the code generator. 15448 // instead of having to edit some template or the code generator.
15606 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 15449 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
15607 15450
15608 } // namespace gles2 15451 } // namespace gles2
15609 } // namespace gpu 15452 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698