| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <list> | 10 #include <list> |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 | 771 |
| 772 // Deletes the texture info for the given texture. | 772 // Deletes the texture info for the given texture. |
| 773 void RemoveTextureInfo(GLuint client_id) { | 773 void RemoveTextureInfo(GLuint client_id) { |
| 774 texture_manager()->RemoveTextureInfo(feature_info_, client_id); | 774 texture_manager()->RemoveTextureInfo(feature_info_, client_id); |
| 775 } | 775 } |
| 776 | 776 |
| 777 // Get the size (in pixels) of the currently bound frame buffer (either FBO | 777 // Get the size (in pixels) of the currently bound frame buffer (either FBO |
| 778 // or regular back buffer). | 778 // or regular back buffer). |
| 779 gfx::Size GetBoundReadFrameBufferSize(); | 779 gfx::Size GetBoundReadFrameBufferSize(); |
| 780 | 780 |
| 781 // Get the format of the currently bound frame buffer (either FBO or regular |
| 782 // back buffer) |
| 783 GLenum GetBoundReadFrameBufferInternalFormat(); |
| 784 |
| 781 // Wrapper for CompressedTexImage2D commands. | 785 // Wrapper for CompressedTexImage2D commands. |
| 782 error::Error DoCompressedTexImage2D( | 786 error::Error DoCompressedTexImage2D( |
| 783 GLenum target, | 787 GLenum target, |
| 784 GLint level, | 788 GLint level, |
| 785 GLenum internal_format, | 789 GLenum internal_format, |
| 786 GLsizei width, | 790 GLsizei width, |
| 787 GLsizei height, | 791 GLsizei height, |
| 788 GLint border, | 792 GLint border, |
| 789 GLsizei image_size, | 793 GLsizei image_size, |
| 790 const void* data); | 794 const void* data); |
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 } else { | 2192 } else { |
| 2189 last_id = 0; | 2193 last_id = 0; |
| 2190 } | 2194 } |
| 2191 | 2195 |
| 2192 glBindTexture(GL_TEXTURE_2D, last_id); | 2196 glBindTexture(GL_TEXTURE_2D, last_id); |
| 2193 glActiveTexture(GL_TEXTURE0 + active_texture_unit_); | 2197 glActiveTexture(GL_TEXTURE0 + active_texture_unit_); |
| 2194 } | 2198 } |
| 2195 | 2199 |
| 2196 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { | 2200 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { |
| 2197 if (bound_read_framebuffer_ != 0) { | 2201 if (bound_read_framebuffer_ != 0) { |
| 2198 int width = 0; | 2202 const FramebufferManager::FramebufferInfo::Attachment* attachment = |
| 2199 int height = 0; | 2203 bound_read_framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); |
| 2200 | 2204 if (attachment) { |
| 2201 GLenum target = | 2205 return gfx::Size(attachment->width(), attachment->height()); |
| 2202 feature_info_->feature_flags().chromium_framebuffer_multisample ? | |
| 2203 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; | |
| 2204 | |
| 2205 // Assume we have to have COLOR_ATTACHMENT0. Should we check for depth and | |
| 2206 // stencil. | |
| 2207 GLint fb_type = 0; | |
| 2208 glGetFramebufferAttachmentParameterivEXT( | |
| 2209 target, | |
| 2210 GL_COLOR_ATTACHMENT0, | |
| 2211 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, | |
| 2212 &fb_type); | |
| 2213 switch (fb_type) { | |
| 2214 case GL_RENDERBUFFER: | |
| 2215 { | |
| 2216 GLint renderbuffer_id = 0; | |
| 2217 glGetFramebufferAttachmentParameterivEXT( | |
| 2218 target, | |
| 2219 GL_COLOR_ATTACHMENT0, | |
| 2220 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, | |
| 2221 &renderbuffer_id); | |
| 2222 if (renderbuffer_id != 0) { | |
| 2223 glGetRenderbufferParameterivEXT( | |
| 2224 GL_RENDERBUFFER, | |
| 2225 GL_RENDERBUFFER_WIDTH, | |
| 2226 &width); | |
| 2227 glGetRenderbufferParameterivEXT( | |
| 2228 GL_RENDERBUFFER, | |
| 2229 GL_RENDERBUFFER_HEIGHT, | |
| 2230 &height); | |
| 2231 } | |
| 2232 break; | |
| 2233 } | |
| 2234 case GL_TEXTURE: | |
| 2235 { | |
| 2236 GLint texture_id = 0; | |
| 2237 glGetFramebufferAttachmentParameterivEXT( | |
| 2238 target, | |
| 2239 GL_COLOR_ATTACHMENT0, | |
| 2240 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, | |
| 2241 &texture_id); | |
| 2242 if (texture_id != 0) { | |
| 2243 GLuint client_id = 0; | |
| 2244 if (texture_manager()->GetClientId(texture_id, &client_id)) { | |
| 2245 TextureManager::TextureInfo* texture_info = | |
| 2246 GetTextureInfo(client_id); | |
| 2247 if (texture_info) { | |
| 2248 GLint level = 0; | |
| 2249 GLint face = 0; | |
| 2250 glGetFramebufferAttachmentParameterivEXT( | |
| 2251 target, | |
| 2252 GL_COLOR_ATTACHMENT0, | |
| 2253 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, | |
| 2254 &level); | |
| 2255 glGetFramebufferAttachmentParameterivEXT( | |
| 2256 target, | |
| 2257 GL_COLOR_ATTACHMENT0, | |
| 2258 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, | |
| 2259 &face); | |
| 2260 texture_info->GetLevelSize( | |
| 2261 face ? face : GL_TEXTURE_2D, level, &width, &height); | |
| 2262 } | |
| 2263 } | |
| 2264 } | |
| 2265 break; | |
| 2266 } | |
| 2267 default: | |
| 2268 // unknown so assume width and height are zero. | |
| 2269 break; | |
| 2270 } | 2206 } |
| 2271 | 2207 return gfx::Size(0, 0); |
| 2272 return gfx::Size(width, height); | |
| 2273 } else if (offscreen_target_frame_buffer_.get()) { | 2208 } else if (offscreen_target_frame_buffer_.get()) { |
| 2274 return offscreen_size_; | 2209 return offscreen_size_; |
| 2275 } else { | 2210 } else { |
| 2276 return context_->GetSize(); | 2211 return context_->GetSize(); |
| 2277 } | 2212 } |
| 2278 } | 2213 } |
| 2279 | 2214 |
| 2215 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { |
| 2216 if (bound_read_framebuffer_ != 0) { |
| 2217 const FramebufferManager::FramebufferInfo::Attachment* attachment = |
| 2218 bound_read_framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); |
| 2219 if (attachment) { |
| 2220 return attachment->internal_format(); |
| 2221 } |
| 2222 return 0; |
| 2223 } else if (offscreen_target_frame_buffer_.get()) { |
| 2224 return offscreen_target_color_format_; |
| 2225 } else { |
| 2226 // TODO(gman): return correct format |
| 2227 return GL_RGBA; |
| 2228 } |
| 2229 } |
| 2230 |
| 2280 bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() { | 2231 bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() { |
| 2281 if (offscreen_size_ == pending_offscreen_size_) | 2232 if (offscreen_size_ == pending_offscreen_size_) |
| 2282 return true; | 2233 return true; |
| 2283 | 2234 |
| 2284 offscreen_size_ = pending_offscreen_size_; | 2235 offscreen_size_ = pending_offscreen_size_; |
| 2285 | 2236 |
| 2286 // Reallocate the offscreen target buffers. | 2237 // Reallocate the offscreen target buffers. |
| 2287 DCHECK(offscreen_target_color_format_); | 2238 DCHECK(offscreen_target_color_format_); |
| 2288 if (IsOffscreenBufferMultisampled()) { | 2239 if (IsOffscreenBufferMultisampled()) { |
| 2289 if (!offscreen_target_color_render_buffer_->AllocateStorage( | 2240 if (!offscreen_target_color_render_buffer_->AllocateStorage( |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3334 RenderbufferManager::RenderbufferInfo* info = NULL; | 3285 RenderbufferManager::RenderbufferInfo* info = NULL; |
| 3335 if (client_renderbuffer_id) { | 3286 if (client_renderbuffer_id) { |
| 3336 info = GetRenderbufferInfo(client_renderbuffer_id); | 3287 info = GetRenderbufferInfo(client_renderbuffer_id); |
| 3337 if (!info) { | 3288 if (!info) { |
| 3338 SetGLError(GL_INVALID_OPERATION, | 3289 SetGLError(GL_INVALID_OPERATION, |
| 3339 "glFramebufferRenderbuffer: unknown renderbuffer"); | 3290 "glFramebufferRenderbuffer: unknown renderbuffer"); |
| 3340 return; | 3291 return; |
| 3341 } | 3292 } |
| 3342 service_id = info->service_id(); | 3293 service_id = info->service_id(); |
| 3343 } | 3294 } |
| 3295 CopyRealGLErrorsToWrapper(); |
| 3344 glFramebufferRenderbufferEXT( | 3296 glFramebufferRenderbufferEXT( |
| 3345 target, attachment, renderbuffertarget, service_id); | 3297 target, attachment, renderbuffertarget, service_id); |
| 3346 if (service_id == 0 || | 3298 GLenum error = glGetError(); |
| 3347 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { | 3299 if (error == GL_NO_ERROR) { |
| 3348 framebuffer_info->AttachRenderbuffer(attachment, info); | 3300 framebuffer_info->AttachRenderbuffer(attachment, info); |
| 3349 if (info) { | 3301 if (service_id == 0 || |
| 3350 ClearUnclearedRenderbuffers(target, framebuffer_info); | 3302 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { |
| 3303 if (info) { |
| 3304 ClearUnclearedRenderbuffers(target, framebuffer_info); |
| 3305 } |
| 3351 } | 3306 } |
| 3352 } | 3307 } |
| 3353 } | 3308 } |
| 3354 | 3309 |
| 3355 void GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { | 3310 void GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { |
| 3356 switch (cap) { | 3311 switch (cap) { |
| 3357 case GL_SCISSOR_TEST: | 3312 case GL_SCISSOR_TEST: |
| 3358 enable_scissor_test_ = enabled; | 3313 enable_scissor_test_ = enabled; |
| 3359 break; | 3314 break; |
| 3360 default: | 3315 default: |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3497 TextureManager::TextureInfo* info = NULL; | 3452 TextureManager::TextureInfo* info = NULL; |
| 3498 if (client_texture_id) { | 3453 if (client_texture_id) { |
| 3499 info = GetTextureInfo(client_texture_id); | 3454 info = GetTextureInfo(client_texture_id); |
| 3500 if (!info) { | 3455 if (!info) { |
| 3501 SetGLError(GL_INVALID_OPERATION, | 3456 SetGLError(GL_INVALID_OPERATION, |
| 3502 "glFramebufferTexture2D: unknown texture"); | 3457 "glFramebufferTexture2D: unknown texture"); |
| 3503 return; | 3458 return; |
| 3504 } | 3459 } |
| 3505 service_id = info->service_id(); | 3460 service_id = info->service_id(); |
| 3506 } | 3461 } |
| 3462 CopyRealGLErrorsToWrapper(); |
| 3507 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); | 3463 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); |
| 3508 if (service_id != 0 && | 3464 GLenum error = glGetError(); |
| 3509 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { | 3465 if (error == GL_NO_ERROR) { |
| 3510 ClearUnclearedRenderbuffers(target, framebuffer_info); | 3466 framebuffer_info->AttachTexture(attachment, info, textarget, level); |
| 3467 if (service_id != 0 && |
| 3468 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { |
| 3469 ClearUnclearedRenderbuffers(target, framebuffer_info); |
| 3470 } |
| 3511 } | 3471 } |
| 3512 } | 3472 } |
| 3513 | 3473 |
| 3514 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( | 3474 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( |
| 3515 GLenum target, GLenum attachment, GLenum pname, GLint* params) { | 3475 GLenum target, GLenum attachment, GLenum pname, GLint* params) { |
| 3516 FramebufferManager::FramebufferInfo* framebuffer_info = | 3476 FramebufferManager::FramebufferInfo* framebuffer_info = |
| 3517 GetFramebufferInfoForTarget(target); | 3477 GetFramebufferInfoForTarget(target); |
| 3518 if (!framebuffer_info) { | 3478 if (!framebuffer_info) { |
| 3519 SetGLError(GL_INVALID_OPERATION, | 3479 SetGLError(GL_INVALID_OPERATION, |
| 3520 "glFramebufferAttachmentParameteriv: no framebuffer bound"); | 3480 "glFramebufferAttachmentParameteriv: no framebuffer bound"); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3574 } | 3534 } |
| 3575 | 3535 |
| 3576 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( | 3536 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( |
| 3577 GLenum target, GLsizei samples, GLenum internalformat, | 3537 GLenum target, GLsizei samples, GLenum internalformat, |
| 3578 GLsizei width, GLsizei height) { | 3538 GLsizei width, GLsizei height) { |
| 3579 if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { | 3539 if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { |
| 3580 SetGLError(GL_INVALID_OPERATION, | 3540 SetGLError(GL_INVALID_OPERATION, |
| 3581 "glRenderbufferStorageMultisampleEXT: function not available"); | 3541 "glRenderbufferStorageMultisampleEXT: function not available"); |
| 3582 return; | 3542 return; |
| 3583 } | 3543 } |
| 3584 bound_renderbuffer_->set_internal_format(internalformat); | |
| 3585 | 3544 |
| 3545 GLenum impl_format = internalformat; |
| 3586 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 3546 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { |
| 3587 switch (internalformat) { | 3547 switch (impl_format) { |
| 3588 case GL_DEPTH_COMPONENT16: | 3548 case GL_DEPTH_COMPONENT16: |
| 3589 internalformat = GL_DEPTH_COMPONENT; | 3549 impl_format = GL_DEPTH_COMPONENT; |
| 3590 break; | 3550 break; |
| 3591 case GL_RGBA4: | 3551 case GL_RGBA4: |
| 3592 case GL_RGB5_A1: | 3552 case GL_RGB5_A1: |
| 3593 internalformat = GL_RGBA; | 3553 impl_format = GL_RGBA; |
| 3594 break; | 3554 break; |
| 3595 case GL_RGB565: | 3555 case GL_RGB565: |
| 3596 internalformat = GL_RGB; | 3556 impl_format = GL_RGB; |
| 3597 break; | 3557 break; |
| 3598 } | 3558 } |
| 3599 } | 3559 } |
| 3600 | 3560 |
| 3561 CopyRealGLErrorsToWrapper(); |
| 3601 glRenderbufferStorageMultisampleEXT( | 3562 glRenderbufferStorageMultisampleEXT( |
| 3602 target, samples, internalformat, width, height); | 3563 target, samples, impl_format, width, height); |
| 3603 // TODO(gman) should not set internal format unless this succeeds | 3564 GLenum error = glGetError(); |
| 3565 if (error == GL_NO_ERROR) { |
| 3566 bound_renderbuffer_->SetInfo(samples, internalformat, width, height); |
| 3567 } |
| 3604 } | 3568 } |
| 3605 | 3569 |
| 3606 void GLES2DecoderImpl::DoRenderbufferStorage( | 3570 void GLES2DecoderImpl::DoRenderbufferStorage( |
| 3607 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { | 3571 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { |
| 3608 if (!bound_renderbuffer_) { | 3572 if (!bound_renderbuffer_) { |
| 3609 SetGLError(GL_INVALID_OPERATION, | 3573 SetGLError(GL_INVALID_OPERATION, |
| 3610 "glGetRenderbufferStorage: no renderbuffer bound"); | 3574 "glGetRenderbufferStorage: no renderbuffer bound"); |
| 3611 return; | 3575 return; |
| 3612 } | 3576 } |
| 3613 bound_renderbuffer_->set_internal_format(internalformat); | |
| 3614 | 3577 |
| 3578 GLenum impl_format = internalformat; |
| 3615 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 3579 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { |
| 3616 switch (internalformat) { | 3580 switch (impl_format) { |
| 3617 case GL_DEPTH_COMPONENT16: | 3581 case GL_DEPTH_COMPONENT16: |
| 3618 internalformat = GL_DEPTH_COMPONENT; | 3582 impl_format = GL_DEPTH_COMPONENT; |
| 3619 break; | 3583 break; |
| 3620 case GL_RGBA4: | 3584 case GL_RGBA4: |
| 3621 case GL_RGB5_A1: | 3585 case GL_RGB5_A1: |
| 3622 internalformat = GL_RGBA; | 3586 impl_format = GL_RGBA; |
| 3623 break; | 3587 break; |
| 3624 case GL_RGB565: | 3588 case GL_RGB565: |
| 3625 internalformat = GL_RGB; | 3589 impl_format = GL_RGB; |
| 3626 break; | 3590 break; |
| 3627 } | 3591 } |
| 3628 } | 3592 } |
| 3629 | 3593 |
| 3630 glRenderbufferStorageEXT(target, internalformat, width, height); | 3594 CopyRealGLErrorsToWrapper(); |
| 3631 // TODO(gman) should not set internal format unless this succeeds | 3595 glRenderbufferStorageEXT(target, impl_format, width, height); |
| 3596 GLenum error = glGetError(); |
| 3597 if (error == GL_NO_ERROR) { |
| 3598 bound_renderbuffer_->SetInfo(0, internalformat, width, height); |
| 3599 } |
| 3632 } | 3600 } |
| 3633 | 3601 |
| 3634 void GLES2DecoderImpl::DoLinkProgram(GLuint program) { | 3602 void GLES2DecoderImpl::DoLinkProgram(GLuint program) { |
| 3635 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( | 3603 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( |
| 3636 program, "glLinkProgram"); | 3604 program, "glLinkProgram"); |
| 3637 if (!info) { | 3605 if (!info) { |
| 3638 return; | 3606 return; |
| 3639 } | 3607 } |
| 3640 if (!info->CanLink()) { | 3608 if (!info->CanLink()) { |
| 3641 return; | 3609 return; |
| (...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5480 "glCopyTexImage2D: unknown texture for target"); | 5448 "glCopyTexImage2D: unknown texture for target"); |
| 5481 return; | 5449 return; |
| 5482 } | 5450 } |
| 5483 if (!texture_manager()->ValidForTarget( | 5451 if (!texture_manager()->ValidForTarget( |
| 5484 feature_info_, target, level, width, height, 1) || | 5452 feature_info_, target, level, width, height, 1) || |
| 5485 border != 0) { | 5453 border != 0) { |
| 5486 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); | 5454 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); |
| 5487 return; | 5455 return; |
| 5488 } | 5456 } |
| 5489 | 5457 |
| 5490 // TODO(gman): Need to check that current FBO is compatible with | 5458 // Check we have compatible formats. |
| 5491 // internal_format. | 5459 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 5492 // TODO(gman): Type needs to match format for FBO. | 5460 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 5461 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); |
| 5462 |
| 5463 if ((channels_needed & channels_exist) != channels_needed) { |
| 5464 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D: incompatible format"); |
| 5465 return; |
| 5466 } |
| 5467 |
| 5493 CopyRealGLErrorsToWrapper(); | 5468 CopyRealGLErrorsToWrapper(); |
| 5494 ScopedResolvedFrameBufferBinder binder(this); | 5469 ScopedResolvedFrameBufferBinder binder(this); |
| 5470 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 5471 |
| 5495 // Clip to size to source dimensions | 5472 // Clip to size to source dimensions |
| 5496 gfx::Size size = GetBoundReadFrameBufferSize(); | |
| 5497 GLint copyX = 0; | 5473 GLint copyX = 0; |
| 5498 GLint copyY = 0; | 5474 GLint copyY = 0; |
| 5499 GLint copyWidth = 0; | 5475 GLint copyWidth = 0; |
| 5500 GLint copyHeight = 0; | 5476 GLint copyHeight = 0; |
| 5501 Clip(x, width, size.width(), ©X, ©Width); | 5477 Clip(x, width, size.width(), ©X, ©Width); |
| 5502 Clip(y, height, size.height(), ©Y, ©Height); | 5478 Clip(y, height, size.height(), ©Y, ©Height); |
| 5503 | 5479 |
| 5504 if (copyX != x || | 5480 if (copyX != x || |
| 5505 copyY != y || | 5481 copyY != y || |
| 5506 copyWidth != width || | 5482 copyWidth != width || |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5555 } | 5531 } |
| 5556 GLenum type = 0; | 5532 GLenum type = 0; |
| 5557 GLenum format = 0; | 5533 GLenum format = 0; |
| 5558 if (!info->GetLevelType(target, level, &type, &format) || | 5534 if (!info->GetLevelType(target, level, &type, &format) || |
| 5559 !info->ValidForTexture( | 5535 !info->ValidForTexture( |
| 5560 target, level, xoffset, yoffset, width, height, format, type)) { | 5536 target, level, xoffset, yoffset, width, height, format, type)) { |
| 5561 SetGLError(GL_INVALID_VALUE, | 5537 SetGLError(GL_INVALID_VALUE, |
| 5562 "glCopyTexSubImage2D: bad dimensions."); | 5538 "glCopyTexSubImage2D: bad dimensions."); |
| 5563 return; | 5539 return; |
| 5564 } | 5540 } |
| 5565 // TODO(gman): Should we check that x, y, width, and height are in range | 5541 |
| 5566 // for current FBO? | 5542 // Check we have compatible formats. |
| 5543 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
| 5544 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
| 5545 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); |
| 5546 |
| 5547 if ((channels_needed & channels_exist) != channels_needed) { |
| 5548 SetGLError( |
| 5549 GL_INVALID_OPERATION, "glCopyTexSubImage2D: incompatible format"); |
| 5550 return; |
| 5551 } |
| 5552 |
| 5567 ScopedResolvedFrameBufferBinder binder(this); | 5553 ScopedResolvedFrameBufferBinder binder(this); |
| 5568 gfx::Size size = GetBoundReadFrameBufferSize(); | 5554 gfx::Size size = GetBoundReadFrameBufferSize(); |
| 5569 GLint copyX = 0; | 5555 GLint copyX = 0; |
| 5570 GLint copyY = 0; | 5556 GLint copyY = 0; |
| 5571 GLint copyWidth = 0; | 5557 GLint copyWidth = 0; |
| 5572 GLint copyHeight = 0; | 5558 GLint copyHeight = 0; |
| 5573 Clip(x, width, size.width(), ©X, ©Width); | 5559 Clip(x, width, size.width(), ©X, ©Width); |
| 5574 Clip(y, height, size.height(), ©Y, ©Height); | 5560 Clip(y, height, size.height(), ©Y, ©Height); |
| 5575 if (copyX != x || | 5561 if (copyX != x || |
| 5576 copyY != y || | 5562 copyY != y || |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6088 return error::kNoError; | 6074 return error::kNoError; |
| 6089 } | 6075 } |
| 6090 | 6076 |
| 6091 // Include the auto-generated part of this file. We split this because it means | 6077 // Include the auto-generated part of this file. We split this because it means |
| 6092 // we can easily edit the non-auto generated parts right here in this file | 6078 // we can easily edit the non-auto generated parts right here in this file |
| 6093 // instead of having to edit some template or the code generator. | 6079 // instead of having to edit some template or the code generator. |
| 6094 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 6080 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 6095 | 6081 |
| 6096 } // namespace gles2 | 6082 } // namespace gles2 |
| 6097 } // namespace gpu | 6083 } // namespace gpu |
| OLD | NEW |