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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 ref_->texture()->OnWillModifyPixels(); | 408 ref_->texture()->OnWillModifyPixels(); |
409 } | 409 } |
410 | 410 |
411 ScopedModifyPixels::~ScopedModifyPixels() { | 411 ScopedModifyPixels::~ScopedModifyPixels() { |
412 if (ref_) | 412 if (ref_) |
413 ref_->texture()->OnDidModifyPixels(); | 413 ref_->texture()->OnDidModifyPixels(); |
414 } | 414 } |
415 | 415 |
416 class ScopedRenderTo { | 416 class ScopedRenderTo { |
417 public: | 417 public: |
418 explicit ScopedRenderTo(Framebuffer* framebuffer); | 418 explicit ScopedRenderTo(Framebuffer* framebuffer) |
419 : ScopedRenderTo(framebuffer, 0) {} | |
420 ScopedRenderTo(Framebuffer* framebuffer, GLenum attachment); | |
419 ~ScopedRenderTo(); | 421 ~ScopedRenderTo(); |
420 | 422 |
421 private: | 423 private: |
422 const Framebuffer* framebuffer_; | 424 const Framebuffer* framebuffer_; |
425 GLenum attachment_; | |
423 }; | 426 }; |
424 | 427 |
425 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer) | 428 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer, GLenum attachment) |
426 : framebuffer_(framebuffer) { | 429 : framebuffer_(framebuffer), |
427 if (framebuffer) | 430 attachment_(attachment) { |
428 framebuffer_->OnWillRenderTo(); | 431 if (framebuffer_) |
432 framebuffer_->OnWillRenderTo(attachment_); | |
429 } | 433 } |
430 | 434 |
431 ScopedRenderTo::~ScopedRenderTo() { | 435 ScopedRenderTo::~ScopedRenderTo() { |
432 if (framebuffer_) | 436 if (framebuffer_) |
433 framebuffer_->OnDidRenderTo(); | 437 framebuffer_->OnDidRenderTo(attachment_); |
434 } | 438 } |
435 | 439 |
436 // Encapsulates an OpenGL texture. | 440 // Encapsulates an OpenGL texture. |
437 class BackTexture { | 441 class BackTexture { |
438 public: | 442 public: |
439 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); | 443 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); |
440 ~BackTexture(); | 444 ~BackTexture(); |
441 | 445 |
442 // Create a new render texture. | 446 // Create a new render texture. |
443 void Create(); | 447 void Create(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 // Get the size (in pixels) of the currently bound frame buffer (either FBO | 902 // Get the size (in pixels) of the currently bound frame buffer (either FBO |
899 // or regular back buffer). | 903 // or regular back buffer). |
900 gfx::Size GetBoundReadFrameBufferSize(); | 904 gfx::Size GetBoundReadFrameBufferSize(); |
901 | 905 |
902 // Get the format/type of the currently bound frame buffer (either FBO or | 906 // Get the format/type of the currently bound frame buffer (either FBO or |
903 // regular back buffer). | 907 // regular back buffer). |
904 // If the color image is a renderbuffer, returns 0 for type. | 908 // If the color image is a renderbuffer, returns 0 for type. |
905 GLenum GetBoundReadFrameBufferTextureType(); | 909 GLenum GetBoundReadFrameBufferTextureType(); |
906 GLenum GetBoundReadFrameBufferInternalFormat(); | 910 GLenum GetBoundReadFrameBufferInternalFormat(); |
907 | 911 |
912 // Get the i-th draw buffer's internal format from the bound framebuffer. | |
913 // If no framebuffer is bound, or no image is attached, or the DrawBuffers | |
914 // setting for that image is GL_NONE, return 0. | |
915 GLenum GetBoundColorDrawBufferInternalFormat(GLint drawbuffer_i); | |
916 | |
917 void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i); | |
918 | |
908 // Wrapper for CompressedTexImage2D commands. | 919 // Wrapper for CompressedTexImage2D commands. |
909 error::Error DoCompressedTexImage2D( | 920 error::Error DoCompressedTexImage2D( |
910 GLenum target, | 921 GLenum target, |
911 GLint level, | 922 GLint level, |
912 GLenum internal_format, | 923 GLenum internal_format, |
913 GLsizei width, | 924 GLsizei width, |
914 GLsizei height, | 925 GLsizei height, |
915 GLint border, | 926 GLint border, |
916 GLsizei image_size, | 927 GLsizei image_size, |
917 const void* data); | 928 const void* data); |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1352 // Check that the currently bound read framebuffer's color image | 1363 // Check that the currently bound read framebuffer's color image |
1353 // isn't the target texture of the glCopyTex{Sub}Image2D. | 1364 // isn't the target texture of the glCopyTex{Sub}Image2D. |
1354 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level); | 1365 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level); |
1355 | 1366 |
1356 // Check if a framebuffer meets our requirements. | 1367 // Check if a framebuffer meets our requirements. |
1357 bool CheckFramebufferValid( | 1368 bool CheckFramebufferValid( |
1358 Framebuffer* framebuffer, | 1369 Framebuffer* framebuffer, |
1359 GLenum target, | 1370 GLenum target, |
1360 const char* func_name); | 1371 const char* func_name); |
1361 | 1372 |
1373 bool CheckBoundDrawFramebufferValid(const char* func_name); | |
1374 | |
1362 // Check if the current valuebuffer exists and is valid. If not generates | 1375 // Check if the current valuebuffer exists and is valid. If not generates |
1363 // the appropriate GL error. Returns true if the current valuebuffer is in | 1376 // the appropriate GL error. Returns true if the current valuebuffer is in |
1364 // a usable state. | 1377 // a usable state. |
1365 bool CheckCurrentValuebuffer(const char* function_name); | 1378 bool CheckCurrentValuebuffer(const char* function_name); |
1366 | 1379 |
1367 // Check if the current valuebuffer exists and is valiud and that the | 1380 // Check if the current valuebuffer exists and is valiud and that the |
1368 // value buffer is actually subscribed to the given subscription | 1381 // value buffer is actually subscribed to the given subscription |
1369 bool CheckCurrentValuebufferForSubscription(GLenum subscription, | 1382 bool CheckCurrentValuebufferForSubscription(GLenum subscription, |
1370 const char* function_name); | 1383 const char* function_name); |
1371 | 1384 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1447 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, | 1460 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, |
1448 GLbitfield mask, GLenum filter); | 1461 GLbitfield mask, GLenum filter); |
1449 | 1462 |
1450 // Wrapper for glBufferSubData. | 1463 // Wrapper for glBufferSubData. |
1451 void DoBufferSubData( | 1464 void DoBufferSubData( |
1452 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); | 1465 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); |
1453 | 1466 |
1454 // Wrapper for glCheckFramebufferStatus | 1467 // Wrapper for glCheckFramebufferStatus |
1455 GLenum DoCheckFramebufferStatus(GLenum target); | 1468 GLenum DoCheckFramebufferStatus(GLenum target); |
1456 | 1469 |
1457 // Wrapper for glClear | 1470 // Wrapper for glClear*() |
1458 error::Error DoClear(GLbitfield mask); | 1471 error::Error DoClear(GLbitfield mask); |
1472 void DoClearBufferiv( | |
1473 GLenum buffer, GLint drawbuffer, const GLint* value); | |
1474 void DoClearBufferuiv( | |
1475 GLenum buffer, GLint drawbuffer, const GLuint* value); | |
1476 void DoClearBufferfv( | |
1477 GLenum buffer, GLint drawbuffer, const GLfloat* value); | |
1478 void DoClearBufferfi( | |
1479 GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); | |
1459 | 1480 |
1460 // Wrappers for various state. | 1481 // Wrappers for various state. |
1461 void DoDepthRangef(GLclampf znear, GLclampf zfar); | 1482 void DoDepthRangef(GLclampf znear, GLclampf zfar); |
1462 void DoSampleCoverage(GLclampf value, GLboolean invert); | 1483 void DoSampleCoverage(GLclampf value, GLboolean invert); |
1463 | 1484 |
1464 // Wrapper for glCompileShader. | 1485 // Wrapper for glCompileShader. |
1465 void DoCompileShader(GLuint shader); | 1486 void DoCompileShader(GLuint shader); |
1466 | 1487 |
1467 // Wrapper for glDetachShader | 1488 // Wrapper for glDetachShader |
1468 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); | 1489 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); |
(...skipping 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3746 return valid; | 3767 return valid; |
3747 } | 3768 } |
3748 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(), | 3769 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(), |
3749 GL_DRAW_FRAMEBUFFER_EXT, | 3770 GL_DRAW_FRAMEBUFFER_EXT, |
3750 func_name) && | 3771 func_name) && |
3751 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(), | 3772 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(), |
3752 GL_READ_FRAMEBUFFER_EXT, | 3773 GL_READ_FRAMEBUFFER_EXT, |
3753 func_name); | 3774 func_name); |
3754 } | 3775 } |
3755 | 3776 |
3777 bool GLES2DecoderImpl::CheckBoundDrawFramebufferValid(const char* func_name) { | |
3778 Framebuffer* framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); | |
3779 if (!framebuffer) { | |
3780 // Assume the default back buffer is always complete. | |
3781 return true; | |
3782 } | |
3783 if (!framebuffer_manager()->IsComplete(framebuffer)) { | |
3784 if (framebuffer->GetStatus(texture_manager(), GL_DRAW_FRAMEBUFFER) != | |
3785 GL_FRAMEBUFFER_COMPLETE) { | |
3786 LOCAL_SET_GL_ERROR( | |
3787 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, | |
3788 "framebuffer incomplete (check)"); | |
3789 return false; | |
3790 } | |
3791 framebuffer_manager()->MarkAsComplete(framebuffer); | |
3792 } | |
3793 return true; | |
3794 } | |
3795 | |
3756 bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment( | 3796 bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment( |
3757 const char* func_name) { | 3797 const char* func_name) { |
3758 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ? | 3798 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ? |
3759 framebuffer_state_.bound_read_framebuffer.get() : | 3799 framebuffer_state_.bound_read_framebuffer.get() : |
3760 framebuffer_state_.bound_draw_framebuffer.get(); | 3800 framebuffer_state_.bound_draw_framebuffer.get(); |
3761 if (!framebuffer) | 3801 if (!framebuffer) |
3762 return true; | 3802 return true; |
3763 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) { | 3803 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) { |
3764 LOCAL_SET_GL_ERROR( | 3804 LOCAL_SET_GL_ERROR( |
3765 GL_INVALID_OPERATION, func_name, "no color image attached"); | 3805 GL_INVALID_OPERATION, func_name, "no color image attached"); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3819 } else { // Back buffer. | 3859 } else { // Back buffer. |
3820 if (back_buffer_read_buffer_ == GL_NONE) | 3860 if (back_buffer_read_buffer_ == GL_NONE) |
3821 return 0; | 3861 return 0; |
3822 if (offscreen_target_frame_buffer_.get()) { | 3862 if (offscreen_target_frame_buffer_.get()) { |
3823 return offscreen_target_color_format_; | 3863 return offscreen_target_color_format_; |
3824 } | 3864 } |
3825 return back_buffer_color_format_; | 3865 return back_buffer_color_format_; |
3826 } | 3866 } |
3827 } | 3867 } |
3828 | 3868 |
3869 GLenum GLES2DecoderImpl::GetBoundColorDrawBufferInternalFormat( | |
3870 GLint drawbuffer_i) { | |
3871 DCHECK(drawbuffer_i >= 0 && | |
3872 drawbuffer_i < static_cast<GLint>(group_->max_draw_buffers())); | |
3873 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER); | |
3874 if (!framebuffer) { | |
3875 return 0; | |
3876 } | |
3877 GLenum drawbuffer = static_cast<GLenum>(GL_DRAW_BUFFER0 + drawbuffer_i); | |
3878 if (framebuffer->GetDrawBuffer(drawbuffer) == GL_NONE) { | |
3879 return 0; | |
3880 } | |
3881 GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer_i); | |
3882 const Framebuffer::Attachment* buffer = | |
3883 framebuffer->GetAttachment(attachment); | |
3884 if (!buffer) { | |
3885 return 0; | |
3886 } | |
3887 return buffer->internal_format(); | |
3888 } | |
3889 | |
3890 void GLES2DecoderImpl::MarkDrawBufferAsCleared( | |
3891 GLenum buffer, GLint drawbuffer_i) { | |
3892 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER); | |
3893 if (!framebuffer) | |
3894 return; | |
3895 GLenum attachment = 0; | |
3896 switch (buffer) { | |
3897 case GL_COLOR: | |
3898 DCHECK(drawbuffer_i >= 0 && | |
3899 drawbuffer_i < static_cast<GLint>(group_->max_draw_buffers())); | |
3900 attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer_i); | |
3901 break; | |
3902 case GL_DEPTH: | |
3903 attachment = GL_DEPTH; | |
3904 break; | |
3905 case GL_STENCIL: | |
3906 attachment = GL_STENCIL; | |
3907 break; | |
3908 default: | |
3909 // Caller is responsible for breaking GL_DEPTH_STENCIL into GL_DEPTH and | |
3910 // GL_STENCIL. | |
3911 NOTREACHED(); | |
3912 } | |
3913 framebuffer->MarkAttachmentAsCleared( | |
3914 renderbuffer_manager(), texture_manager(), attachment, true); | |
3915 } | |
3916 | |
3829 void GLES2DecoderImpl::UpdateParentTextureInfo() { | 3917 void GLES2DecoderImpl::UpdateParentTextureInfo() { |
3830 if (!offscreen_saved_color_texture_info_.get()) | 3918 if (!offscreen_saved_color_texture_info_.get()) |
3831 return; | 3919 return; |
3832 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); | 3920 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); |
3833 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); | 3921 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); |
3834 texture_manager()->SetLevelInfo( | 3922 texture_manager()->SetLevelInfo( |
3835 offscreen_saved_color_texture_info_.get(), GL_TEXTURE_2D, | 3923 offscreen_saved_color_texture_info_.get(), GL_TEXTURE_2D, |
3836 0, // level | 3924 0, // level |
3837 GL_RGBA, offscreen_size_.width(), offscreen_size_.height(), | 3925 GL_RGBA, offscreen_size_.width(), offscreen_size_.height(), |
3838 1, // depth | 3926 1, // depth |
(...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5654 GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); | 5742 GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); |
5655 } | 5743 } |
5656 } | 5744 } |
5657 return error::kNoError; | 5745 return error::kNoError; |
5658 } | 5746 } |
5659 | 5747 |
5660 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { | 5748 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { |
5661 DCHECK(!ShouldDeferDraws()); | 5749 DCHECK(!ShouldDeferDraws()); |
5662 if (CheckBoundFramebuffersValid("glClear")) { | 5750 if (CheckBoundFramebuffersValid("glClear")) { |
5663 ApplyDirtyState(); | 5751 ApplyDirtyState(); |
5752 // TODO(zmo): Filter out INTEGER/SIGNED INTEGER images to avoid | |
5753 // undefined results. | |
5664 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); | 5754 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); |
5665 if (workarounds().gl_clear_broken) { | 5755 if (workarounds().gl_clear_broken) { |
5666 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", | 5756 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", |
5667 GetErrorState()); | 5757 GetErrorState()); |
5668 if (!BoundFramebufferHasDepthAttachment()) | 5758 if (!BoundFramebufferHasDepthAttachment()) |
5669 mask &= ~GL_DEPTH_BUFFER_BIT; | 5759 mask &= ~GL_DEPTH_BUFFER_BIT; |
5670 if (!BoundFramebufferHasStencilAttachment()) | 5760 if (!BoundFramebufferHasStencilAttachment()) |
5671 mask &= ~GL_STENCIL_BUFFER_BIT; | 5761 mask &= ~GL_STENCIL_BUFFER_BIT; |
5672 clear_framebuffer_blit_->ClearFramebuffer( | 5762 clear_framebuffer_blit_->ClearFramebuffer( |
5673 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red, | 5763 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red, |
5674 state_.color_clear_green, state_.color_clear_blue, | 5764 state_.color_clear_green, state_.color_clear_blue, |
5675 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear); | 5765 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear); |
5676 return error::kNoError; | 5766 return error::kNoError; |
5677 } | 5767 } |
5678 glClear(mask); | 5768 glClear(mask); |
5679 } | 5769 } |
5680 return error::kNoError; | 5770 return error::kNoError; |
5681 } | 5771 } |
5682 | 5772 |
5773 void GLES2DecoderImpl::DoClearBufferiv( | |
5774 GLenum buffer, GLint drawbuffer, const GLint* value) { | |
5775 if (!CheckBoundDrawFramebufferValid("glClearBufferiv")) | |
5776 return; | |
5777 ApplyDirtyState(); | |
5778 | |
5779 switch (buffer) { | |
5780 case GL_COLOR: | |
5781 case GL_STENCIL: | |
5782 break; | |
5783 default: | |
5784 LOCAL_SET_GL_ERROR( | |
5785 GL_INVALID_ENUM, "glClearBufferiv", "invalid buffer"); | |
5786 return; | |
5787 } | |
5788 GLenum attachment = 0; | |
5789 if (buffer == GL_COLOR) { | |
5790 if (drawbuffer < 0 || | |
5791 drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) { | |
5792 LOCAL_SET_GL_ERROR( | |
5793 GL_INVALID_VALUE, "glClearBufferiv", "invalid drawBuffer"); | |
5794 return; | |
5795 } | |
5796 GLenum internal_format = | |
5797 GetBoundColorDrawBufferInternalFormat(drawbuffer); | |
5798 if (!GLES2Util::IsSignedIntegerFormat(internal_format)) { | |
no sievers
2015/08/26 21:44:20
Is 'unsigned int' here really part of the undefine
Zhenyao Mo
2015/08/26 23:09:55
For example, how do you convert a negative value t
| |
5799 // To avoid undefined results, return without calling the gl function. | |
5800 return; | |
5801 } | |
5802 attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer); | |
5803 } else { | |
5804 DCHECK(buffer == GL_STENCIL); | |
5805 if (drawbuffer != 0) { | |
5806 LOCAL_SET_GL_ERROR( | |
5807 GL_INVALID_VALUE, "glClearBufferiv", "invalid drawBuffer"); | |
5808 return; | |
5809 } | |
5810 if (!BoundFramebufferHasStencilAttachment()) { | |
5811 return; | |
5812 } | |
5813 attachment = GL_STENCIL_ATTACHMENT; | |
5814 } | |
5815 MarkDrawBufferAsCleared(buffer, drawbuffer); | |
5816 { | |
5817 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(), | |
5818 attachment); | |
5819 glClearBufferiv(buffer, drawbuffer, value); | |
5820 } | |
5821 } | |
5822 | |
5823 void GLES2DecoderImpl::DoClearBufferuiv( | |
5824 GLenum buffer, GLint drawbuffer, const GLuint* value) { | |
5825 if (!CheckBoundDrawFramebufferValid("glClearBufferuiv")) | |
5826 return; | |
5827 ApplyDirtyState(); | |
5828 | |
5829 switch (buffer) { | |
5830 case GL_COLOR: | |
5831 break; | |
5832 default: | |
5833 LOCAL_SET_GL_ERROR( | |
5834 GL_INVALID_ENUM, "glClearBufferuiv", "invalid buffer"); | |
5835 return; | |
5836 } | |
5837 if (drawbuffer < 0 || | |
5838 drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) { | |
5839 LOCAL_SET_GL_ERROR( | |
5840 GL_INVALID_VALUE, "glClearBufferuiv", "invalid drawBuffer"); | |
5841 return; | |
5842 } | |
5843 GLenum internal_format = | |
5844 GetBoundColorDrawBufferInternalFormat(drawbuffer); | |
5845 if (!GLES2Util::IsUnsignedIntegerFormat(internal_format)) { | |
5846 // To avoid undefined results, return without calling the gl function. | |
5847 return; | |
5848 } | |
5849 MarkDrawBufferAsCleared(buffer, drawbuffer); | |
5850 GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer); | |
5851 { | |
5852 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(), | |
5853 attachment); | |
5854 glClearBufferuiv(buffer, drawbuffer, value); | |
5855 } | |
5856 } | |
5857 | |
5858 void GLES2DecoderImpl::DoClearBufferfv( | |
5859 GLenum buffer, GLint drawbuffer, const GLfloat* value) { | |
5860 if (!CheckBoundDrawFramebufferValid("glClearBufferfv")) | |
5861 return; | |
5862 ApplyDirtyState(); | |
5863 | |
5864 switch (buffer) { | |
5865 case GL_COLOR: | |
5866 case GL_DEPTH: | |
5867 break; | |
5868 default: | |
5869 LOCAL_SET_GL_ERROR( | |
5870 GL_INVALID_ENUM, "glClearBufferfv", "invalid buffer"); | |
5871 return; | |
5872 } | |
5873 GLenum attachment = 0; | |
5874 if (buffer == GL_COLOR) { | |
5875 if (drawbuffer < 0 || | |
5876 drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) { | |
5877 LOCAL_SET_GL_ERROR( | |
5878 GL_INVALID_VALUE, "glClearBufferfv", "invalid drawBuffer"); | |
5879 return; | |
5880 } | |
5881 GLenum internal_format = | |
5882 GetBoundColorDrawBufferInternalFormat(drawbuffer); | |
5883 if (GLES2Util::IsIntegerFormat(internal_format)) { | |
5884 // To avoid undefined results, return without calling the gl function. | |
5885 return; | |
5886 } | |
5887 attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer); | |
5888 } else { | |
5889 DCHECK(buffer == GL_DEPTH); | |
5890 if (drawbuffer != 0) { | |
5891 LOCAL_SET_GL_ERROR( | |
5892 GL_INVALID_VALUE, "glClearBufferfv", "invalid drawBuffer"); | |
5893 return; | |
5894 } | |
5895 if (!BoundFramebufferHasDepthAttachment()) { | |
5896 return; | |
5897 } | |
5898 attachment = GL_DEPTH_ATTACHMENT; | |
5899 } | |
5900 MarkDrawBufferAsCleared(buffer, drawbuffer); | |
5901 { | |
5902 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(), | |
5903 attachment); | |
5904 glClearBufferfv(buffer, drawbuffer, value); | |
5905 } | |
5906 } | |
5907 | |
5908 void GLES2DecoderImpl::DoClearBufferfi( | |
5909 GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { | |
5910 if (!CheckBoundDrawFramebufferValid("glClearBufferfi")) | |
5911 return; | |
5912 ApplyDirtyState(); | |
5913 | |
5914 switch (buffer) { | |
5915 case GL_DEPTH_STENCIL: | |
5916 break; | |
5917 default: | |
5918 LOCAL_SET_GL_ERROR( | |
5919 GL_INVALID_ENUM, "glClearBufferfi", "invalid buffer"); | |
5920 return; | |
5921 } | |
5922 if (drawbuffer != 0) { | |
5923 LOCAL_SET_GL_ERROR( | |
5924 GL_INVALID_VALUE, "glClearBufferfi", "invalid drawBuffer"); | |
5925 return; | |
5926 } | |
5927 if (!BoundFramebufferHasDepthAttachment() && | |
no sievers
2015/08/26 21:44:20
'&& -> ||' ?
Zhenyao Mo
2015/08/26 23:09:55
We still need to call the clear() if one of the de
| |
5928 !BoundFramebufferHasStencilAttachment()) { | |
5929 return; | |
5930 } | |
5931 MarkDrawBufferAsCleared(GL_DEPTH, drawbuffer); | |
5932 MarkDrawBufferAsCleared(GL_STENCIL, drawbuffer); | |
5933 { | |
5934 ScopedRenderTo do_render_depth( | |
5935 framebuffer_state_.bound_draw_framebuffer.get(), | |
5936 GL_DEPTH_ATTACHMENT); | |
5937 ScopedRenderTo do_render_stencil( | |
5938 framebuffer_state_.bound_draw_framebuffer.get(), | |
5939 GL_STENCIL_ATTACHMENT); | |
5940 glClearBufferfi(buffer, drawbuffer, depth, stencil); | |
5941 } | |
5942 } | |
5943 | |
5683 void GLES2DecoderImpl::DoFramebufferRenderbuffer( | 5944 void GLES2DecoderImpl::DoFramebufferRenderbuffer( |
5684 GLenum target, GLenum attachment, GLenum renderbuffertarget, | 5945 GLenum target, GLenum attachment, GLenum renderbuffertarget, |
5685 GLuint client_renderbuffer_id) { | 5946 GLuint client_renderbuffer_id) { |
5686 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); | 5947 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); |
5687 if (!framebuffer) { | 5948 if (!framebuffer) { |
5688 LOCAL_SET_GL_ERROR( | 5949 LOCAL_SET_GL_ERROR( |
5689 GL_INVALID_OPERATION, | 5950 GL_INVALID_OPERATION, |
5690 "glFramebufferRenderbuffer", "no framebuffer bound"); | 5951 "glFramebufferRenderbuffer", "no framebuffer bound"); |
5691 return; | 5952 return; |
5692 } | 5953 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5751 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id()); | 6012 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id()); |
5752 } | 6013 } |
5753 GLbitfield clear_bits = 0; | 6014 GLbitfield clear_bits = 0; |
5754 if (framebuffer->HasUnclearedColorAttachments()) { | 6015 if (framebuffer->HasUnclearedColorAttachments()) { |
5755 // We should always use alpha == 0 here, because 1) some draw buffers may | 6016 // We should always use alpha == 0 here, because 1) some draw buffers may |
5756 // have alpha and some may not; 2) we won't have the same situation as the | 6017 // have alpha and some may not; 2) we won't have the same situation as the |
5757 // back buffer where alpha channel exists but is not requested. | 6018 // back buffer where alpha channel exists but is not requested. |
5758 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 6019 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
5759 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 6020 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
5760 clear_bits |= GL_COLOR_BUFFER_BIT; | 6021 clear_bits |= GL_COLOR_BUFFER_BIT; |
5761 if (feature_info_->feature_flags().ext_draw_buffers) | 6022 if (feature_info_->feature_flags().ext_draw_buffers || |
6023 feature_info_->IsES3Enabled()) { | |
5762 framebuffer->PrepareDrawBuffersForClear(); | 6024 framebuffer->PrepareDrawBuffersForClear(); |
6025 } | |
5763 } | 6026 } |
5764 | 6027 |
5765 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || | 6028 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || |
5766 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { | 6029 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { |
5767 glClearStencil(0); | 6030 glClearStencil(0); |
5768 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); | 6031 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); |
5769 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); | 6032 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); |
5770 clear_bits |= GL_STENCIL_BUFFER_BIT; | 6033 clear_bits |= GL_STENCIL_BUFFER_BIT; |
5771 } | 6034 } |
5772 | 6035 |
5773 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || | 6036 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || |
5774 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { | 6037 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { |
5775 glClearDepth(1.0f); | 6038 glClearDepth(1.0f); |
5776 state_.SetDeviceDepthMask(GL_TRUE); | 6039 state_.SetDeviceDepthMask(GL_TRUE); |
5777 clear_bits |= GL_DEPTH_BUFFER_BIT; | 6040 clear_bits |= GL_DEPTH_BUFFER_BIT; |
5778 } | 6041 } |
5779 | 6042 |
5780 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); | 6043 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); |
5781 glClear(clear_bits); | 6044 glClear(clear_bits); |
5782 | 6045 |
5783 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 && | 6046 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 && |
5784 feature_info_->feature_flags().ext_draw_buffers) | 6047 (feature_info_->feature_flags().ext_draw_buffers || |
6048 feature_info_->IsES3Enabled())) { | |
5785 framebuffer->RestoreDrawBuffersAfterClear(); | 6049 framebuffer->RestoreDrawBuffersAfterClear(); |
6050 } | |
6051 | |
6052 if (feature_info_->IsES3Enabled()) { | |
6053 // TODO(zmo): track more state to know whether there are any integer | |
6054 // buffers attached to the current framebuffer. | |
6055 framebuffer->ClearIntegerBuffers(); | |
6056 } | |
5786 | 6057 |
5787 framebuffer_manager()->MarkAttachmentsAsCleared( | 6058 framebuffer_manager()->MarkAttachmentsAsCleared( |
5788 framebuffer, renderbuffer_manager(), texture_manager()); | 6059 framebuffer, renderbuffer_manager(), texture_manager()); |
5789 | 6060 |
5790 RestoreClearState(); | 6061 RestoreClearState(); |
5791 | 6062 |
5792 if (target == GL_READ_FRAMEBUFFER_EXT) { | 6063 if (target == GL_READ_FRAMEBUFFER_EXT) { |
5793 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id()); | 6064 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id()); |
5794 Framebuffer* draw_framebuffer = | 6065 Framebuffer* draw_framebuffer = |
5795 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); | 6066 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); |
(...skipping 8987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14783 return error::kNoError; | 15054 return error::kNoError; |
14784 } | 15055 } |
14785 | 15056 |
14786 // Include the auto-generated part of this file. We split this because it means | 15057 // Include the auto-generated part of this file. We split this because it means |
14787 // we can easily edit the non-auto generated parts right here in this file | 15058 // we can easily edit the non-auto generated parts right here in this file |
14788 // instead of having to edit some template or the code generator. | 15059 // instead of having to edit some template or the code generator. |
14789 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 15060 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
14790 | 15061 |
14791 } // namespace gles2 | 15062 } // namespace gles2 |
14792 } // namespace gpu | 15063 } // namespace gpu |
OLD | NEW |