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/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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 } | 184 } |
185 | 185 |
186 struct Vec4f { | 186 struct Vec4f { |
187 explicit Vec4f(const Vec4& data) { | 187 explicit Vec4f(const Vec4& data) { |
188 data.GetValues(v); | 188 data.GetValues(v); |
189 } | 189 } |
190 | 190 |
191 GLfloat v[4]; | 191 GLfloat v[4]; |
192 }; | 192 }; |
193 | 193 |
194 // Returns the union of |rect1| and |rect2| if one of the rectangles is empty, | |
195 // contains the other rectangle or shares an edge with the other rectangle. | |
196 bool CombineAdjacentRects(const gfx::Rect& rect1, | |
197 const gfx::Rect& rect2, | |
198 gfx::Rect* result) { | |
199 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|. | |
200 if (rect1.IsEmpty() || rect2.Contains(rect1)) { | |
201 *result = rect2; | |
202 return true; | |
203 } | |
204 | |
205 // Return |rect1| if |rect2| is empty or |rect1| contains |rect2|. | |
206 if (rect2.IsEmpty() || rect1.Contains(rect2)) { | |
207 *result = rect1; | |
208 return true; | |
209 } | |
210 | |
211 // Return the union of |rect1| and |rect2| if they share an edge. | |
212 if (rect1.SharesEdgeWith(rect2)) { | |
213 *result = gfx::UnionRects(rect1, rect2); | |
214 return true; | |
215 } | |
216 | |
217 // Return false if it's not possible to combine |rect1| and |rect2|. | |
218 return false; | |
219 } | |
220 | |
194 } // namespace | 221 } // namespace |
195 | 222 |
196 class GLES2DecoderImpl; | 223 class GLES2DecoderImpl; |
197 | 224 |
198 // Local versions of the SET_GL_ERROR macros | 225 // Local versions of the SET_GL_ERROR macros |
199 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ | 226 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ |
200 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) | 227 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) |
201 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ | 228 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ |
202 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ | 229 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ |
203 function_name, value, label) | 230 function_name, value, label) |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1263 bool ClearUnclearedTextures(); | 1290 bool ClearUnclearedTextures(); |
1264 | 1291 |
1265 // Clears any uncleared attachments attached to the given frame buffer. | 1292 // Clears any uncleared attachments attached to the given frame buffer. |
1266 // Returns false if there was a generated GL error. | 1293 // Returns false if there was a generated GL error. |
1267 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); | 1294 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); |
1268 | 1295 |
1269 // overridden from GLES2Decoder | 1296 // overridden from GLES2Decoder |
1270 bool ClearLevel(Texture* texture, | 1297 bool ClearLevel(Texture* texture, |
1271 unsigned target, | 1298 unsigned target, |
1272 int level, | 1299 int level, |
1273 unsigned internal_format, | |
1274 unsigned format, | 1300 unsigned format, |
1275 unsigned type, | 1301 unsigned type, |
1302 int xoffset, | |
1303 int yoffset, | |
1276 int width, | 1304 int width, |
1277 int height, | 1305 int height) override; |
1278 bool is_texture_immutable) override; | |
1279 | 1306 |
1280 // Restore all GL state that affects clearing. | 1307 // Restore all GL state that affects clearing. |
1281 void RestoreClearState(); | 1308 void RestoreClearState(); |
1282 | 1309 |
1283 // Remembers the state of some capabilities. | 1310 // Remembers the state of some capabilities. |
1284 // Returns: true if glEnable/glDisable should actually be called. | 1311 // Returns: true if glEnable/glDisable should actually be called. |
1285 bool SetCapabilityState(GLenum cap, bool enabled); | 1312 bool SetCapabilityState(GLenum cap, bool enabled); |
1286 | 1313 |
1287 // Check that the currently bound framebuffers are valid. | 1314 // Check that the currently bound framebuffers are valid. |
1288 // Generates GL error if not. | 1315 // Generates GL error if not. |
(...skipping 2254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3543 | 3570 |
3544 GLenum completeness = framebuffer->IsPossiblyComplete(); | 3571 GLenum completeness = framebuffer->IsPossiblyComplete(); |
3545 if (completeness != GL_FRAMEBUFFER_COMPLETE) { | 3572 if (completeness != GL_FRAMEBUFFER_COMPLETE) { |
3546 LOCAL_SET_GL_ERROR( | 3573 LOCAL_SET_GL_ERROR( |
3547 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); | 3574 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); |
3548 return false; | 3575 return false; |
3549 } | 3576 } |
3550 | 3577 |
3551 // Are all the attachments cleared? | 3578 // Are all the attachments cleared? |
3552 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || | 3579 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || |
3553 texture_manager()->HaveUnclearedMips()) { | 3580 texture_manager()->HaveUnsafeTextures()) { |
3554 if (!framebuffer->IsCleared()) { | 3581 if (!framebuffer->IsCleared()) { |
3555 // Can we clear them? | 3582 // Can we clear them? |
3556 if (framebuffer->GetStatus(texture_manager(), target) != | 3583 if (framebuffer->GetStatus(texture_manager(), target) != |
3557 GL_FRAMEBUFFER_COMPLETE) { | 3584 GL_FRAMEBUFFER_COMPLETE) { |
3558 LOCAL_SET_GL_ERROR( | 3585 LOCAL_SET_GL_ERROR( |
3559 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, | 3586 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, |
3560 "framebuffer incomplete (clear)"); | 3587 "framebuffer incomplete (clear)"); |
3561 return false; | 3588 return false; |
3562 } | 3589 } |
3563 ClearUnclearedAttachments(target, framebuffer); | 3590 ClearUnclearedAttachments(target, framebuffer); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3678 return back_buffer_color_format_; | 3705 return back_buffer_color_format_; |
3679 } | 3706 } |
3680 } | 3707 } |
3681 | 3708 |
3682 void GLES2DecoderImpl::UpdateParentTextureInfo() { | 3709 void GLES2DecoderImpl::UpdateParentTextureInfo() { |
3683 if (!offscreen_saved_color_texture_info_.get()) | 3710 if (!offscreen_saved_color_texture_info_.get()) |
3684 return; | 3711 return; |
3685 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); | 3712 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); |
3686 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); | 3713 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); |
3687 texture_manager()->SetLevelInfo( | 3714 texture_manager()->SetLevelInfo( |
3688 offscreen_saved_color_texture_info_.get(), | 3715 offscreen_saved_color_texture_info_.get(), GL_TEXTURE_2D, |
3689 GL_TEXTURE_2D, | |
3690 0, // level | 3716 0, // level |
3691 GL_RGBA, | 3717 GL_RGBA, offscreen_size_.width(), offscreen_size_.height(), |
3692 offscreen_size_.width(), | |
3693 offscreen_size_.height(), | |
3694 1, // depth | 3718 1, // depth |
3695 0, // border | 3719 0, // border |
3696 GL_RGBA, | 3720 GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(offscreen_size_)); |
3697 GL_UNSIGNED_BYTE, | |
3698 true); | |
3699 texture_manager()->SetParameteri( | 3721 texture_manager()->SetParameteri( |
3700 "UpdateParentTextureInfo", | 3722 "UpdateParentTextureInfo", |
3701 GetErrorState(), | 3723 GetErrorState(), |
3702 offscreen_saved_color_texture_info_.get(), | 3724 offscreen_saved_color_texture_info_.get(), |
3703 GL_TEXTURE_MAG_FILTER, | 3725 GL_TEXTURE_MAG_FILTER, |
3704 GL_LINEAR); | 3726 GL_LINEAR); |
3705 texture_manager()->SetParameteri( | 3727 texture_manager()->SetParameteri( |
3706 "UpdateParentTextureInfo", | 3728 "UpdateParentTextureInfo", |
3707 GetErrorState(), | 3729 GetErrorState(), |
3708 offscreen_saved_color_texture_info_.get(), | 3730 offscreen_saved_color_texture_info_.get(), |
(...skipping 5149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8858 return error::kNoError; | 8880 return error::kNoError; |
8859 } | 8881 } |
8860 | 8882 |
8861 void GLES2DecoderImpl::DoBufferSubData( | 8883 void GLES2DecoderImpl::DoBufferSubData( |
8862 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { | 8884 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { |
8863 // Just delegate it. Some validation is actually done before this. | 8885 // Just delegate it. Some validation is actually done before this. |
8864 buffer_manager()->ValidateAndDoBufferSubData( | 8886 buffer_manager()->ValidateAndDoBufferSubData( |
8865 &state_, target, offset, size, data); | 8887 &state_, target, offset, size, data); |
8866 } | 8888 } |
8867 | 8889 |
8868 bool GLES2DecoderImpl::ClearLevel( | 8890 bool GLES2DecoderImpl::ClearLevel(Texture* texture, |
8869 Texture* texture, | 8891 unsigned target, |
8870 unsigned target, | 8892 int level, |
8871 int level, | 8893 unsigned format, |
8872 unsigned internal_format, | 8894 unsigned type, |
8873 unsigned format, | 8895 int xoffset, |
8874 unsigned type, | 8896 int yoffset, |
8875 int width, | 8897 int width, |
8876 int height, | 8898 int height) { |
8877 bool is_texture_immutable) { | |
8878 uint32 channels = GLES2Util::GetChannelsForFormat(format); | 8899 uint32 channels = GLES2Util::GetChannelsForFormat(format); |
8879 if (feature_info_->feature_flags().angle_depth_texture && | 8900 if (feature_info_->feature_flags().angle_depth_texture && |
8880 (channels & GLES2Util::kDepth) != 0) { | 8901 (channels & GLES2Util::kDepth) != 0 && xoffset == 0 && yoffset == 0) { |
8881 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D | 8902 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D |
8882 // on depth formats. | 8903 // on depth formats. |
piman
2015/06/05 19:55:49
It sounds like this is still true in the xoffset !
reveman
2015/06/05 20:39:43
Yes, I was trying to avoid that but we have to han
| |
8883 GLuint fb = 0; | 8904 GLuint fb = 0; |
8884 glGenFramebuffersEXT(1, &fb); | 8905 glGenFramebuffersEXT(1, &fb); |
8885 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); | 8906 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); |
8886 | 8907 |
8887 bool have_stencil = (channels & GLES2Util::kStencil) != 0; | 8908 bool have_stencil = (channels & GLES2Util::kStencil) != 0; |
8888 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : | 8909 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : |
8889 GL_DEPTH_ATTACHMENT; | 8910 GL_DEPTH_ATTACHMENT; |
8890 | 8911 |
8891 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target, | 8912 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target, |
8892 texture->service_id(), level); | 8913 texture->service_id(), level); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8943 } | 8964 } |
8944 } else { | 8965 } else { |
8945 tile_height = height; | 8966 tile_height = height; |
8946 } | 8967 } |
8947 | 8968 |
8948 // Assumes the size has already been checked. | 8969 // Assumes the size has already been checked. |
8949 scoped_ptr<char[]> zero(new char[size]); | 8970 scoped_ptr<char[]> zero(new char[size]); |
8950 memset(zero.get(), 0, size); | 8971 memset(zero.get(), 0, size); |
8951 glBindTexture(texture->target(), texture->service_id()); | 8972 glBindTexture(texture->target(), texture->service_id()); |
8952 | 8973 |
8953 bool has_images = texture->HasImages(); | |
8954 GLint y = 0; | 8974 GLint y = 0; |
8955 while (y < height) { | 8975 while (y < height) { |
8956 GLint h = y + tile_height > height ? height - y : tile_height; | 8976 GLint h = y + tile_height > height ? height - y : tile_height; |
8957 if (is_texture_immutable || h != height || has_images) { | 8977 glTexSubImage2D(target, level, xoffset, yoffset + y, width, h, format, type, |
8958 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); | 8978 zero.get()); |
8959 } else { | |
8960 glTexImage2D( | |
8961 target, level, internal_format, width, h, 0, format, type, | |
8962 zero.get()); | |
8963 } | |
8964 y += tile_height; | 8979 y += tile_height; |
8965 } | 8980 } |
8966 TextureRef* bound_texture = | 8981 TextureRef* bound_texture = |
8967 texture_manager()->GetTextureInfoForTarget(&state_, texture->target()); | 8982 texture_manager()->GetTextureInfoForTarget(&state_, texture->target()); |
8968 glBindTexture(texture->target(), | 8983 glBindTexture(texture->target(), |
8969 bound_texture ? bound_texture->service_id() : 0); | 8984 bound_texture ? bound_texture->service_id() : 0); |
8970 return true; | 8985 return true; |
8971 } | 8986 } |
8972 | 8987 |
8973 namespace { | 8988 namespace { |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9314 if (!data) { | 9329 if (!data) { |
9315 zero.reset(new int8[image_size]); | 9330 zero.reset(new int8[image_size]); |
9316 memset(zero.get(), 0, image_size); | 9331 memset(zero.get(), 0, image_size); |
9317 data = zero.get(); | 9332 data = zero.get(); |
9318 } | 9333 } |
9319 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); | 9334 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); |
9320 glCompressedTexImage2D( | 9335 glCompressedTexImage2D( |
9321 target, level, internal_format, width, height, border, image_size, data); | 9336 target, level, internal_format, width, height, border, image_size, data); |
9322 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); | 9337 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); |
9323 if (error == GL_NO_ERROR) { | 9338 if (error == GL_NO_ERROR) { |
9324 texture_manager()->SetLevelInfo( | 9339 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
9325 texture_ref, target, level, internal_format, | 9340 width, height, 1, border, 0, 0, |
9326 width, height, 1, border, 0, 0, true); | 9341 gfx::Rect(width, height)); |
9327 } | 9342 } |
9328 | 9343 |
9329 // This may be a slow command. Exit command processing to allow for | 9344 // This may be a slow command. Exit command processing to allow for |
9330 // context preemption and GPU watchdog checks. | 9345 // context preemption and GPU watchdog checks. |
9331 ExitCommandProcessingEarly(); | 9346 ExitCommandProcessingEarly(); |
9332 return error::kNoError; | 9347 return error::kNoError; |
9333 } | 9348 } |
9334 | 9349 |
9335 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( | 9350 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( |
9336 uint32 immediate_data_size, | 9351 uint32 immediate_data_size, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9501 if (!data) { | 9516 if (!data) { |
9502 zero.reset(new int8[image_size]); | 9517 zero.reset(new int8[image_size]); |
9503 memset(zero.get(), 0, image_size); | 9518 memset(zero.get(), 0, image_size); |
9504 data = zero.get(); | 9519 data = zero.get(); |
9505 } | 9520 } |
9506 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); | 9521 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); |
9507 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | 9522 glCompressedTexImage3D(target, level, internal_format, width, height, depth, |
9508 border, image_size, data); | 9523 border, image_size, data); |
9509 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); | 9524 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); |
9510 if (error == GL_NO_ERROR) { | 9525 if (error == GL_NO_ERROR) { |
9511 texture_manager()->SetLevelInfo( | 9526 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
9512 texture_ref, target, level, internal_format, | 9527 width, height, depth, border, 0, 0, |
9513 width, height, depth, border, 0, 0, true); | 9528 gfx::Rect(width, height)); |
9514 } | 9529 } |
9515 | 9530 |
9516 // This may be a slow command. Exit command processing to allow for | 9531 // This may be a slow command. Exit command processing to allow for |
9517 // context preemption and GPU watchdog checks. | 9532 // context preemption and GPU watchdog checks. |
9518 ExitCommandProcessingEarly(); | 9533 ExitCommandProcessingEarly(); |
9519 return error::kNoError; | 9534 return error::kNoError; |
9520 } | 9535 } |
9521 | 9536 |
9522 error::Error GLES2DecoderImpl::HandleCompressedTexImage3D( | 9537 error::Error GLES2DecoderImpl::HandleCompressedTexImage3D( |
9523 uint32 immediate_data_size, const void* cmd_data) { | 9538 uint32 immediate_data_size, const void* cmd_data) { |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9967 GLint copyY = 0; | 9982 GLint copyY = 0; |
9968 GLint copyWidth = 0; | 9983 GLint copyWidth = 0; |
9969 GLint copyHeight = 0; | 9984 GLint copyHeight = 0; |
9970 Clip(x, width, size.width(), ©X, ©Width); | 9985 Clip(x, width, size.width(), ©X, ©Width); |
9971 Clip(y, height, size.height(), ©Y, ©Height); | 9986 Clip(y, height, size.height(), ©Y, ©Height); |
9972 | 9987 |
9973 if (copyX != x || | 9988 if (copyX != x || |
9974 copyY != y || | 9989 copyY != y || |
9975 copyWidth != width || | 9990 copyWidth != width || |
9976 copyHeight != height) { | 9991 copyHeight != height) { |
9977 // some part was clipped so clear the texture. | 9992 // some part was clipped so clear the rect. |
9978 if (!ClearLevel(texture, target, level, internal_format, internal_format, | 9993 uint32 pixels_size = 0; |
9979 GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) { | 9994 if (!GLES2Util::ComputeImageDataSizes( |
9995 width, height, 1, internal_format, GL_UNSIGNED_BYTE, | |
9996 state_.unpack_alignment, &pixels_size, NULL, NULL)) { | |
9980 LOCAL_SET_GL_ERROR( | 9997 LOCAL_SET_GL_ERROR( |
9981 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); | 9998 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); |
9982 return; | 9999 return; |
9983 } | 10000 } |
10001 scoped_ptr<char[]> zero(new char[pixels_size]); | |
10002 memset(zero.get(), 0, pixels_size); | |
10003 ScopedModifyPixels modify(texture_ref); | |
10004 glTexImage2D(target, level, internal_format, width, height, border, | |
10005 internal_format, GL_UNSIGNED_BYTE, zero.get()); | |
reveman
2015/06/05 19:38:37
I changed this code to be more consistent with DoC
piman
2015/06/05 19:55:50
That's a nice catch, thanks!
| |
9984 if (copyHeight > 0 && copyWidth > 0) { | 10006 if (copyHeight > 0 && copyWidth > 0) { |
9985 GLint dx = copyX - x; | 10007 GLint dx = copyX - x; |
9986 GLint dy = copyY - y; | 10008 GLint dy = copyY - y; |
9987 GLint destX = dx; | 10009 GLint destX = dx; |
9988 GLint destY = dy; | 10010 GLint destY = dy; |
9989 ScopedModifyPixels modify(texture_ref); | 10011 ScopedModifyPixels modify(texture_ref); |
piman
2015/06/05 19:55:50
Can ScopedModifyPixels be nested? Maybe just remov
reveman
2015/06/05 20:39:43
Done.
| |
9990 glCopyTexSubImage2D(target, level, | 10012 glCopyTexSubImage2D(target, level, |
9991 destX, destY, copyX, copyY, | 10013 destX, destY, copyX, copyY, |
9992 copyWidth, copyHeight); | 10014 copyWidth, copyHeight); |
9993 } | 10015 } |
9994 } else { | 10016 } else { |
9995 ScopedModifyPixels modify(texture_ref); | 10017 ScopedModifyPixels modify(texture_ref); |
9996 glCopyTexImage2D(target, level, internal_format, | 10018 glCopyTexImage2D(target, level, internal_format, |
9997 copyX, copyY, copyWidth, copyHeight, border); | 10019 copyX, copyY, copyWidth, copyHeight, border); |
9998 } | 10020 } |
9999 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); | 10021 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); |
10000 if (error == GL_NO_ERROR) { | 10022 if (error == GL_NO_ERROR) { |
10001 texture_manager()->SetLevelInfo( | 10023 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
10002 texture_ref, target, level, internal_format, width, height, 1, | 10024 width, height, 1, border, internal_format, |
10003 border, internal_format, GL_UNSIGNED_BYTE, true); | 10025 GL_UNSIGNED_BYTE, gfx::Rect(width, height)); |
10004 } | 10026 } |
10005 | 10027 |
10006 // This may be a slow command. Exit command processing to allow for | 10028 // This may be a slow command. Exit command processing to allow for |
10007 // context preemption and GPU watchdog checks. | 10029 // context preemption and GPU watchdog checks. |
10008 ExitCommandProcessingEarly(); | 10030 ExitCommandProcessingEarly(); |
10009 } | 10031 } |
10010 | 10032 |
10011 void GLES2DecoderImpl::DoCopyTexSubImage2D( | 10033 void GLES2DecoderImpl::DoCopyTexSubImage2D( |
10012 GLenum target, | 10034 GLenum target, |
10013 GLint level, | 10035 GLint level, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10081 gfx::Size size = GetBoundReadFrameBufferSize(); | 10103 gfx::Size size = GetBoundReadFrameBufferSize(); |
10082 GLint copyX = 0; | 10104 GLint copyX = 0; |
10083 GLint copyY = 0; | 10105 GLint copyY = 0; |
10084 GLint copyWidth = 0; | 10106 GLint copyWidth = 0; |
10085 GLint copyHeight = 0; | 10107 GLint copyHeight = 0; |
10086 Clip(x, width, size.width(), ©X, ©Width); | 10108 Clip(x, width, size.width(), ©X, ©Width); |
10087 Clip(y, height, size.height(), ©Y, ©Height); | 10109 Clip(y, height, size.height(), ©Y, ©Height); |
10088 | 10110 |
10089 if (xoffset != 0 || yoffset != 0 || width != size.width() || | 10111 if (xoffset != 0 || yoffset != 0 || width != size.width() || |
10090 height != size.height()) { | 10112 height != size.height()) { |
10091 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, | 10113 gfx::Rect cleared_rect; |
10092 level)) { | 10114 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level), |
10093 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", | 10115 gfx::Rect(xoffset, yoffset, width, height), |
10094 "dimensions too big"); | 10116 &cleared_rect)) { |
10095 return; | 10117 DCHECK_GE(cleared_rect.size().GetArea(), |
10118 texture->GetLevelClearedRect(target, level).size().GetArea()); | |
10119 texture_manager()->SetLevelClearedRect(texture_ref, target, level, | |
10120 cleared_rect); | |
10121 } else { | |
10122 // Otherwise clear part of texture level that is not already cleared. | |
10123 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, | |
10124 level)) { | |
10125 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", | |
10126 "dimensions too big"); | |
10127 return; | |
10128 } | |
10096 } | 10129 } |
10097 } else { | 10130 } else { |
10098 // Write all pixels in below. | 10131 // Write all pixels in below. |
10099 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | 10132 texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
10100 } | 10133 } |
10101 | 10134 |
10102 if (copyX != x || | 10135 if (copyX != x || |
10103 copyY != y || | 10136 copyY != y || |
10104 copyWidth != width || | 10137 copyWidth != width || |
10105 copyHeight != height) { | 10138 copyHeight != height) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10230 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 10263 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
10231 &state_, target); | 10264 &state_, target); |
10232 Texture* texture = texture_ref->texture(); | 10265 Texture* texture = texture_ref->texture(); |
10233 GLsizei tex_width = 0; | 10266 GLsizei tex_width = 0; |
10234 GLsizei tex_height = 0; | 10267 GLsizei tex_height = 0; |
10235 bool ok = texture->GetLevelSize( | 10268 bool ok = texture->GetLevelSize( |
10236 target, level, &tex_width, &tex_height, nullptr); | 10269 target, level, &tex_width, &tex_height, nullptr); |
10237 DCHECK(ok); | 10270 DCHECK(ok); |
10238 if (xoffset != 0 || yoffset != 0 || | 10271 if (xoffset != 0 || yoffset != 0 || |
10239 width != tex_width || height != tex_height) { | 10272 width != tex_width || height != tex_height) { |
10240 if (!texture_manager()->ClearTextureLevel(this, texture_ref, | 10273 gfx::Rect cleared_rect; |
10241 target, level)) { | 10274 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level), |
10242 LOCAL_SET_GL_ERROR( | 10275 gfx::Rect(xoffset, yoffset, width, height), |
10243 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); | 10276 &cleared_rect)) { |
10244 return error::kNoError; | 10277 DCHECK_GE(cleared_rect.size().GetArea(), |
10278 texture->GetLevelClearedRect(target, level).size().GetArea()); | |
10279 texture_manager()->SetLevelClearedRect(texture_ref, target, level, | |
10280 cleared_rect); | |
10281 } else { | |
10282 // Otherwise clear part of texture level that is not already cleared. | |
10283 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, | |
10284 level)) { | |
10285 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexSubImage2D", | |
10286 "dimensions too big"); | |
10287 return error::kNoError; | |
10288 } | |
10245 } | 10289 } |
10246 ScopedTextureUploadTimer timer(&texture_state_); | 10290 ScopedTextureUploadTimer timer(&texture_state_); |
10247 glTexSubImage2D( | 10291 glTexSubImage2D( |
10248 target, level, xoffset, yoffset, width, height, format, type, data); | 10292 target, level, xoffset, yoffset, width, height, format, type, data); |
10249 return error::kNoError; | 10293 return error::kNoError; |
10250 } | 10294 } |
10251 | 10295 |
10252 if (!texture_state_.texsubimage_faster_than_teximage && | 10296 if (!texture_state_.texsubimage_faster_than_teximage && |
10253 !texture->IsImmutable() && | 10297 !texture->IsImmutable() && |
10254 !texture->HasImages()) { | 10298 !texture->HasImages()) { |
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11750 plane); | 11794 plane); |
11751 | 11795 |
11752 if (err != kCGLNoError) { | 11796 if (err != kCGLNoError) { |
11753 LOCAL_SET_GL_ERROR( | 11797 LOCAL_SET_GL_ERROR( |
11754 GL_INVALID_OPERATION, | 11798 GL_INVALID_OPERATION, |
11755 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D"); | 11799 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D"); |
11756 return; | 11800 return; |
11757 } | 11801 } |
11758 | 11802 |
11759 texture_manager()->SetLevelInfo( | 11803 texture_manager()->SetLevelInfo( |
11760 texture_ref, target, 0, GL_RGBA, width, height, 1, 0, | 11804 texture_ref, target, 0, GL_RGBA, width, height, 1, 0, GL_BGRA, |
11761 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); | 11805 GL_UNSIGNED_INT_8_8_8_8_REV, gfx::Rect(width, height)); |
11762 | 11806 |
11763 #else | 11807 #else |
11764 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, | 11808 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
11765 "glTexImageIOSurface2DCHROMIUM", "not supported."); | 11809 "glTexImageIOSurface2DCHROMIUM", "not supported."); |
11766 #endif | 11810 #endif |
11767 } | 11811 } |
11768 | 11812 |
11769 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { | 11813 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { |
11770 switch (internalformat) { | 11814 switch (internalformat) { |
11771 case GL_RGB565: | 11815 case GL_RGB565: |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11974 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height, | 12018 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height, |
11975 0, internal_format, dest_type, NULL); | 12019 0, internal_format, dest_type, NULL); |
11976 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); | 12020 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); |
11977 if (error != GL_NO_ERROR) { | 12021 if (error != GL_NO_ERROR) { |
11978 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D); | 12022 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D); |
11979 return; | 12023 return; |
11980 } | 12024 } |
11981 | 12025 |
11982 texture_manager()->SetLevelInfo( | 12026 texture_manager()->SetLevelInfo( |
11983 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width, | 12027 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width, |
11984 source_height, 1, 0, internal_format, dest_type, true); | 12028 source_height, 1, 0, internal_format, dest_type, |
12029 gfx::Rect(source_width, source_height)); | |
11985 } else { | 12030 } else { |
11986 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, | 12031 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, |
11987 true); | 12032 true); |
11988 } | 12033 } |
11989 | 12034 |
11990 ScopedModifyPixels modify(dest_texture_ref); | 12035 ScopedModifyPixels modify(dest_texture_ref); |
11991 | 12036 |
11992 // Try using GLImage::CopyTexSubImage when possible. | 12037 // Try using GLImage::CopyTexSubImage when possible. |
11993 bool unpack_premultiply_alpha_change = | 12038 bool unpack_premultiply_alpha_change = |
11994 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_; | 12039 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12120 return; | 12165 return; |
12121 } | 12166 } |
12122 | 12167 |
12123 int dest_width = 0; | 12168 int dest_width = 0; |
12124 int dest_height = 0; | 12169 int dest_height = 0; |
12125 bool ok = dest_texture->GetLevelSize( | 12170 bool ok = dest_texture->GetLevelSize( |
12126 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); | 12171 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); |
12127 DCHECK(ok); | 12172 DCHECK(ok); |
12128 if (xoffset != 0 || yoffset != 0 || width != dest_width || | 12173 if (xoffset != 0 || yoffset != 0 || width != dest_width || |
12129 height != dest_height) { | 12174 height != dest_height) { |
12130 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, | 12175 gfx::Rect cleared_rect; |
12131 0)) { | 12176 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0), |
12132 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", | 12177 gfx::Rect(xoffset, yoffset, width, height), |
12133 "destination texture dimensions too big"); | 12178 &cleared_rect)) { |
12134 return; | 12179 DCHECK_GE(cleared_rect.size().GetArea(), |
12180 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); | |
12181 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, | |
12182 cleared_rect); | |
12183 } else { | |
12184 // Otherwise clear part of texture level that is not already cleared. | |
12185 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, | |
12186 0)) { | |
12187 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", | |
12188 "destination texture dimensions too big"); | |
12189 return; | |
12190 } | |
12135 } | 12191 } |
12136 } else { | 12192 } else { |
12137 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, | 12193 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, |
12138 true); | 12194 true); |
12139 } | 12195 } |
12140 | 12196 |
12141 ScopedModifyPixels modify(dest_texture_ref); | 12197 ScopedModifyPixels modify(dest_texture_ref); |
12142 | 12198 |
12143 // Try using GLImage::CopyTexSubImage when possible. | 12199 // Try using GLImage::CopyTexSubImage when possible. |
12144 bool unpack_premultiply_alpha_change = | 12200 bool unpack_premultiply_alpha_change = |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12270 } | 12326 } |
12271 } | 12327 } |
12272 | 12328 |
12273 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); | 12329 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); |
12274 glTexStorage2DEXT(target, levels, internal_format, width, height); | 12330 glTexStorage2DEXT(target, levels, internal_format, width, height); |
12275 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); | 12331 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); |
12276 if (error == GL_NO_ERROR) { | 12332 if (error == GL_NO_ERROR) { |
12277 GLsizei level_width = width; | 12333 GLsizei level_width = width; |
12278 GLsizei level_height = height; | 12334 GLsizei level_height = height; |
12279 for (int ii = 0; ii < levels; ++ii) { | 12335 for (int ii = 0; ii < levels; ++ii) { |
12280 texture_manager()->SetLevelInfo( | 12336 texture_manager()->SetLevelInfo(texture_ref, target, ii, format, |
12281 texture_ref, target, ii, format, | 12337 level_width, level_height, 1, 0, format, |
12282 level_width, level_height, 1, 0, format, type, false); | 12338 type, gfx::Rect()); |
12283 level_width = std::max(1, level_width >> 1); | 12339 level_width = std::max(1, level_width >> 1); |
12284 level_height = std::max(1, level_height >> 1); | 12340 level_height = std::max(1, level_height >> 1); |
12285 } | 12341 } |
12286 texture->SetImmutable(true); | 12342 texture->SetImmutable(true); |
12287 } | 12343 } |
12288 } | 12344 } |
12289 | 12345 |
12290 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( | 12346 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( |
12291 uint32 immediate_data_size, | 12347 uint32 immediate_data_size, |
12292 const void* cmd_data) { | 12348 const void* cmd_data) { |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12622 if (!gl_image->BindTexImage(target)) { | 12678 if (!gl_image->BindTexImage(target)) { |
12623 LOCAL_SET_GL_ERROR( | 12679 LOCAL_SET_GL_ERROR( |
12624 GL_INVALID_OPERATION, | 12680 GL_INVALID_OPERATION, |
12625 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID"); | 12681 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID"); |
12626 return; | 12682 return; |
12627 } | 12683 } |
12628 } | 12684 } |
12629 | 12685 |
12630 gfx::Size size = gl_image->GetSize(); | 12686 gfx::Size size = gl_image->GetSize(); |
12631 texture_manager()->SetLevelInfo( | 12687 texture_manager()->SetLevelInfo( |
12632 texture_ref, target, 0, gl_image->GetInternalFormat(), | 12688 texture_ref, target, 0, gl_image->GetInternalFormat(), size.width(), |
12633 size.width(), size.height(), 1, 0, | 12689 size.height(), 1, 0, gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, |
12634 gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, true); | 12690 gfx::Rect(size)); |
12635 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image); | 12691 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image); |
12636 } | 12692 } |
12637 | 12693 |
12638 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( | 12694 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( |
12639 GLenum target, GLint image_id) { | 12695 GLenum target, GLint image_id) { |
12640 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); | 12696 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); |
12641 | 12697 |
12642 // Default target might be conceptually valid, but disallow it to avoid | 12698 // Default target might be conceptually valid, but disallow it to avoid |
12643 // accidents. | 12699 // accidents. |
12644 TextureRef* texture_ref = | 12700 TextureRef* texture_ref = |
(...skipping 18 matching lines...) Expand all Loading... | |
12663 return; | 12719 return; |
12664 | 12720 |
12665 { | 12721 { |
12666 ScopedGLErrorSuppressor suppressor( | 12722 ScopedGLErrorSuppressor suppressor( |
12667 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState()); | 12723 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState()); |
12668 gl_image->ReleaseTexImage(target); | 12724 gl_image->ReleaseTexImage(target); |
12669 } | 12725 } |
12670 | 12726 |
12671 texture_manager()->SetLevelInfo( | 12727 texture_manager()->SetLevelInfo( |
12672 texture_ref, target, 0, gl_image->GetInternalFormat(), 0, 0, 1, 0, | 12728 texture_ref, target, 0, gl_image->GetInternalFormat(), 0, 0, 1, 0, |
12673 gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, false); | 12729 gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect()); |
12674 } | 12730 } |
12675 | 12731 |
12676 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( | 12732 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( |
12677 uint32 immediate_data_size, | 12733 uint32 immediate_data_size, |
12678 const void* cmd_data) { | 12734 const void* cmd_data) { |
12679 const gles2::cmds::TraceBeginCHROMIUM& c = | 12735 const gles2::cmds::TraceBeginCHROMIUM& c = |
12680 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data); | 12736 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data); |
12681 Bucket* category_bucket = GetBucket(c.category_bucket_id); | 12737 Bucket* category_bucket = GetBucket(c.category_bucket_id); |
12682 Bucket* name_bucket = GetBucket(c.name_bucket_id); | 12738 Bucket* name_bucket = GetBucket(c.name_bucket_id); |
12683 if (!category_bucket || category_bucket->size() == 0 || | 12739 if (!category_bucket || category_bucket->size() == 0 || |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13310 } | 13366 } |
13311 } | 13367 } |
13312 | 13368 |
13313 // Include the auto-generated part of this file. We split this because it means | 13369 // Include the auto-generated part of this file. We split this because it means |
13314 // we can easily edit the non-auto generated parts right here in this file | 13370 // we can easily edit the non-auto generated parts right here in this file |
13315 // instead of having to edit some template or the code generator. | 13371 // instead of having to edit some template or the code generator. |
13316 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 13372 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
13317 | 13373 |
13318 } // namespace gles2 | 13374 } // namespace gles2 |
13319 } // namespace gpu | 13375 } // namespace gpu |
OLD | NEW |