| 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 <limits.h> | 7 #include <limits.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 // Encapsulates an OpenGL render buffer of any format. | 387 // Encapsulates an OpenGL render buffer of any format. |
| 388 class BackRenderbuffer { | 388 class BackRenderbuffer { |
| 389 public: | 389 public: |
| 390 explicit BackRenderbuffer(GLES2DecoderImpl* decoder); | 390 explicit BackRenderbuffer(GLES2DecoderImpl* decoder); |
| 391 ~BackRenderbuffer(); | 391 ~BackRenderbuffer(); |
| 392 | 392 |
| 393 // Create a new render buffer. | 393 // Create a new render buffer. |
| 394 void Create(); | 394 void Create(); |
| 395 | 395 |
| 396 // Set the initial size and format of a render buffer or resize it. | 396 // Set the initial size and format of a render buffer or resize it. |
| 397 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples); | 397 bool AllocateStorage(const FeatureInfo* feature_info, |
| 398 const gfx::Size& size, |
| 399 GLenum format, |
| 400 GLsizei samples); |
| 398 | 401 |
| 399 // Destroy the render buffer. This must be explicitly called before destroying | 402 // Destroy the render buffer. This must be explicitly called before destroying |
| 400 // this object. | 403 // this object. |
| 401 void Destroy(); | 404 void Destroy(); |
| 402 | 405 |
| 403 // Invalidate the render buffer. This can be used when a context is lost and | 406 // Invalidate the render buffer. This can be used when a context is lost and |
| 404 // it is not possible to make it current in order to free the resource. | 407 // it is not possible to make it current in order to free the resource. |
| 405 void Invalidate(); | 408 void Invalidate(); |
| 406 | 409 |
| 407 GLuint id() const { | 410 GLuint id() const { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 bool BoundFramebufferHasStencilAttachment(); | 624 bool BoundFramebufferHasStencilAttachment(); |
| 622 | 625 |
| 623 // Overriden from ErrorStateClient. | 626 // Overriden from ErrorStateClient. |
| 624 void OnContextLostError() override; | 627 void OnContextLostError() override; |
| 625 void OnOutOfMemoryError() override; | 628 void OnOutOfMemoryError() override; |
| 626 | 629 |
| 627 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound. | 630 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound. |
| 628 void EnsureRenderbufferBound(); | 631 void EnsureRenderbufferBound(); |
| 629 | 632 |
| 630 // Helpers to facilitate calling into compatible extensions. | 633 // Helpers to facilitate calling into compatible extensions. |
| 631 void RenderbufferStorageMultisampleWithWorkaround(GLenum target, | 634 static void RenderbufferStorageMultisampleHelper( |
| 632 GLsizei samples, | 635 const FeatureInfo* feature_info, |
| 633 GLenum internal_format, | 636 GLenum target, |
| 634 GLsizei width, | 637 GLsizei samples, |
| 635 GLsizei height); | 638 GLenum internal_format, |
| 636 void RenderbufferStorageMultisampleHelper(GLenum target, | 639 GLsizei width, |
| 637 GLsizei samples, | 640 GLsizei height); |
| 638 GLenum internal_format, | |
| 639 GLsizei width, | |
| 640 GLsizei height); | |
| 641 bool RegenerateRenderbufferIfNeeded(Renderbuffer* renderbuffer); | |
| 642 | 641 |
| 643 void BlitFramebufferHelper(GLint srcX0, | 642 void BlitFramebufferHelper(GLint srcX0, |
| 644 GLint srcY0, | 643 GLint srcY0, |
| 645 GLint srcX1, | 644 GLint srcX1, |
| 646 GLint srcY1, | 645 GLint srcY1, |
| 647 GLint dstX0, | 646 GLint dstX0, |
| 648 GLint dstY0, | 647 GLint dstY0, |
| 649 GLint dstX1, | 648 GLint dstX1, |
| 650 GLint dstY1, | 649 GLint dstY1, |
| 651 GLbitfield mask, | 650 GLbitfield mask, |
| (...skipping 2250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2902 DCHECK_EQ(id_, 0u); | 2901 DCHECK_EQ(id_, 0u); |
| 2903 } | 2902 } |
| 2904 | 2903 |
| 2905 void BackRenderbuffer::Create() { | 2904 void BackRenderbuffer::Create() { |
| 2906 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", | 2905 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", |
| 2907 decoder_->state_.GetErrorState()); | 2906 decoder_->state_.GetErrorState()); |
| 2908 Destroy(); | 2907 Destroy(); |
| 2909 glGenRenderbuffersEXT(1, &id_); | 2908 glGenRenderbuffersEXT(1, &id_); |
| 2910 } | 2909 } |
| 2911 | 2910 |
| 2912 bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, | 2911 bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info, |
| 2912 const gfx::Size& size, |
| 2913 GLenum format, | 2913 GLenum format, |
| 2914 GLsizei samples) { | 2914 GLsizei samples) { |
| 2915 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage", | 2915 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage", |
| 2916 decoder_->state_.GetErrorState()); | 2916 decoder_->state_.GetErrorState()); |
| 2917 ScopedRenderBufferBinder binder(&decoder_->state_, id_); | 2917 ScopedRenderBufferBinder binder(&decoder_->state_, id_); |
| 2918 | 2918 |
| 2919 uint32_t estimated_size = 0; | 2919 uint32_t estimated_size = 0; |
| 2920 if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize( | 2920 if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize( |
| 2921 size.width(), size.height(), samples, format, &estimated_size)) { | 2921 size.width(), size.height(), samples, format, &estimated_size)) { |
| 2922 return false; | 2922 return false; |
| 2923 } | 2923 } |
| 2924 | 2924 |
| 2925 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) { | 2925 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) { |
| 2926 return false; | 2926 return false; |
| 2927 } | 2927 } |
| 2928 | 2928 |
| 2929 // TODO(kainino): "samples <= 1" is technically incorrect (it should be | |
| 2930 // "samples == 0"), but it causes framebuffer incompleteness in some | |
| 2931 // situations. Once this is fixed, this entire arm is no longer necessary - | |
| 2932 // RenderbufferStorageMultisampleHelper implements it. http://crbug.com/731286 | |
| 2933 if (samples <= 1) { | 2929 if (samples <= 1) { |
| 2934 glRenderbufferStorageEXT(GL_RENDERBUFFER, | 2930 glRenderbufferStorageEXT(GL_RENDERBUFFER, |
| 2935 format, | 2931 format, |
| 2936 size.width(), | 2932 size.width(), |
| 2937 size.height()); | 2933 size.height()); |
| 2938 } else { | 2934 } else { |
| 2939 // TODO(kainino): This path will not perform RegenerateRenderbufferIfNeeded | 2935 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info, |
| 2940 // on devices where multisample_renderbuffer_resize_emulation is needed. | 2936 GL_RENDERBUFFER, |
| 2941 // Thus any code using this path (pepper?) could encounter issues on those | 2937 samples, |
| 2942 // devices. RenderbufferStorageMultisampleWithWorkaround should be used | 2938 format, |
| 2943 // instead, but can only be used if BackRenderbuffer tracks its | 2939 size.width(), |
| 2944 // renderbuffers in the renderbuffer manager instead of manually. | 2940 size.height()); |
| 2945 // http://crbug.com/731287 | |
| 2946 decoder_->RenderbufferStorageMultisampleHelper( | |
| 2947 GL_RENDERBUFFER, samples, format, size.width(), size.height()); | |
| 2948 } | 2941 } |
| 2949 | 2942 |
| 2950 bool alpha_channel_needs_clear = | 2943 bool alpha_channel_needs_clear = |
| 2951 (format == GL_RGBA || format == GL_RGBA8) && | 2944 (format == GL_RGBA || format == GL_RGBA8) && |
| 2952 !decoder_->offscreen_buffer_should_have_alpha_; | 2945 !decoder_->offscreen_buffer_should_have_alpha_; |
| 2953 if (alpha_channel_needs_clear) { | 2946 if (alpha_channel_needs_clear) { |
| 2954 GLuint fbo; | 2947 GLuint fbo; |
| 2955 glGenFramebuffersEXT(1, &fbo); | 2948 glGenFramebuffersEXT(1, &fbo); |
| 2956 { | 2949 { |
| 2957 ScopedFramebufferBinder binder(decoder_, fbo); | 2950 ScopedFramebufferBinder binder(decoder_, fbo); |
| (...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5052 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { | 5045 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { |
| 5053 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " | 5046 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " |
| 5054 << "to allocate storage due to excessive dimensions."; | 5047 << "to allocate storage due to excessive dimensions."; |
| 5055 return false; | 5048 return false; |
| 5056 } | 5049 } |
| 5057 | 5050 |
| 5058 // Reallocate the offscreen target buffers. | 5051 // Reallocate the offscreen target buffers. |
| 5059 DCHECK(offscreen_target_color_format_); | 5052 DCHECK(offscreen_target_color_format_); |
| 5060 if (IsOffscreenBufferMultisampled()) { | 5053 if (IsOffscreenBufferMultisampled()) { |
| 5061 if (!offscreen_target_color_render_buffer_->AllocateStorage( | 5054 if (!offscreen_target_color_render_buffer_->AllocateStorage( |
| 5062 offscreen_size_, offscreen_target_color_format_, | 5055 feature_info_.get(), offscreen_size_, |
| 5063 offscreen_target_samples_)) { | 5056 offscreen_target_color_format_, offscreen_target_samples_)) { |
| 5064 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " | 5057 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " |
| 5065 << "to allocate storage for offscreen target color buffer."; | 5058 << "to allocate storage for offscreen target color buffer."; |
| 5066 return false; | 5059 return false; |
| 5067 } | 5060 } |
| 5068 } else { | 5061 } else { |
| 5069 if (!offscreen_target_color_texture_->AllocateStorage( | 5062 if (!offscreen_target_color_texture_->AllocateStorage( |
| 5070 offscreen_size_, offscreen_target_color_format_, false)) { | 5063 offscreen_size_, offscreen_target_color_format_, false)) { |
| 5071 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " | 5064 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " |
| 5072 << "to allocate storage for offscreen target color texture."; | 5065 << "to allocate storage for offscreen target color texture."; |
| 5073 return false; | 5066 return false; |
| 5074 } | 5067 } |
| 5075 } | 5068 } |
| 5076 if (offscreen_target_depth_format_ && | 5069 if (offscreen_target_depth_format_ && |
| 5077 !offscreen_target_depth_render_buffer_->AllocateStorage( | 5070 !offscreen_target_depth_render_buffer_->AllocateStorage( |
| 5078 offscreen_size_, offscreen_target_depth_format_, | 5071 feature_info_.get(), |
| 5072 offscreen_size_, |
| 5073 offscreen_target_depth_format_, |
| 5079 offscreen_target_samples_)) { | 5074 offscreen_target_samples_)) { |
| 5080 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " | 5075 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " |
| 5081 << "to allocate storage for offscreen target depth buffer."; | 5076 << "to allocate storage for offscreen target depth buffer."; |
| 5082 return false; | 5077 return false; |
| 5083 } | 5078 } |
| 5084 if (offscreen_target_stencil_format_ && | 5079 if (offscreen_target_stencil_format_ && |
| 5085 !offscreen_target_stencil_render_buffer_->AllocateStorage( | 5080 !offscreen_target_stencil_render_buffer_->AllocateStorage( |
| 5086 offscreen_size_, offscreen_target_stencil_format_, | 5081 feature_info_.get(), |
| 5082 offscreen_size_, |
| 5083 offscreen_target_stencil_format_, |
| 5087 offscreen_target_samples_)) { | 5084 offscreen_target_samples_)) { |
| 5088 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " | 5085 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed " |
| 5089 << "to allocate storage for offscreen target stencil buffer."; | 5086 << "to allocate storage for offscreen target stencil buffer."; |
| 5090 return false; | 5087 return false; |
| 5091 } | 5088 } |
| 5092 | 5089 |
| 5093 // Attach the offscreen target buffers to the target frame buffer. | 5090 // Attach the offscreen target buffers to the target frame buffer. |
| 5094 if (IsOffscreenBufferMultisampled()) { | 5091 if (IsOffscreenBufferMultisampled()) { |
| 5095 offscreen_target_frame_buffer_->AttachRenderBuffer( | 5092 offscreen_target_frame_buffer_->AttachRenderBuffer( |
| 5096 GL_COLOR_ATTACHMENT0, | 5093 GL_COLOR_ATTACHMENT0, |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5759 // backbuffer. | 5756 // backbuffer. |
| 5760 if (framebuffer == NULL) { | 5757 if (framebuffer == NULL) { |
| 5761 service_id = GetBackbufferServiceId(); | 5758 service_id = GetBackbufferServiceId(); |
| 5762 } | 5759 } |
| 5763 | 5760 |
| 5764 glBindFramebufferEXT(target, service_id); | 5761 glBindFramebufferEXT(target, service_id); |
| 5765 OnFboChanged(); | 5762 OnFboChanged(); |
| 5766 } | 5763 } |
| 5767 | 5764 |
| 5768 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { | 5765 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { |
| 5769 DCHECK_EQ(target, (GLenum)GL_RENDERBUFFER); | |
| 5770 Renderbuffer* renderbuffer = NULL; | 5766 Renderbuffer* renderbuffer = NULL; |
| 5771 GLuint service_id = 0; | 5767 GLuint service_id = 0; |
| 5772 if (client_id != 0) { | 5768 if (client_id != 0) { |
| 5773 renderbuffer = GetRenderbuffer(client_id); | 5769 renderbuffer = GetRenderbuffer(client_id); |
| 5774 if (!renderbuffer) { | 5770 if (!renderbuffer) { |
| 5775 if (!group_->bind_generates_resource()) { | 5771 if (!group_->bind_generates_resource()) { |
| 5776 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, | 5772 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 5777 "glBindRenderbuffer", | 5773 "glBindRenderbuffer", |
| 5778 "id not generated by glGenRenderbuffers"); | 5774 "id not generated by glGenRenderbuffers"); |
| 5779 return; | 5775 return; |
| (...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8383 void GLES2DecoderImpl::EnsureRenderbufferBound() { | 8379 void GLES2DecoderImpl::EnsureRenderbufferBound() { |
| 8384 if (!state_.bound_renderbuffer_valid) { | 8380 if (!state_.bound_renderbuffer_valid) { |
| 8385 state_.bound_renderbuffer_valid = true; | 8381 state_.bound_renderbuffer_valid = true; |
| 8386 glBindRenderbufferEXT(GL_RENDERBUFFER, | 8382 glBindRenderbufferEXT(GL_RENDERBUFFER, |
| 8387 state_.bound_renderbuffer.get() | 8383 state_.bound_renderbuffer.get() |
| 8388 ? state_.bound_renderbuffer->service_id() | 8384 ? state_.bound_renderbuffer->service_id() |
| 8389 : 0); | 8385 : 0); |
| 8390 } | 8386 } |
| 8391 } | 8387 } |
| 8392 | 8388 |
| 8393 void GLES2DecoderImpl::RenderbufferStorageMultisampleWithWorkaround( | 8389 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( |
| 8390 const FeatureInfo* feature_info, |
| 8394 GLenum target, | 8391 GLenum target, |
| 8395 GLsizei samples, | 8392 GLsizei samples, |
| 8396 GLenum internal_format, | 8393 GLenum internal_format, |
| 8397 GLsizei width, | 8394 GLsizei width, |
| 8398 GLsizei height) { | 8395 GLsizei height) { |
| 8399 RegenerateRenderbufferIfNeeded(state_.bound_renderbuffer.get()); | |
| 8400 EnsureRenderbufferBound(); | |
| 8401 RenderbufferStorageMultisampleHelper(target, samples, internal_format, width, | |
| 8402 height); | |
| 8403 } | |
| 8404 | |
| 8405 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( | |
| 8406 GLenum target, | |
| 8407 GLsizei samples, | |
| 8408 GLenum internal_format, | |
| 8409 GLsizei width, | |
| 8410 GLsizei height) { | |
| 8411 if (samples == 0) { | |
| 8412 glRenderbufferStorageEXT(target, internal_format, width, height); | |
| 8413 return; | |
| 8414 } | |
| 8415 | |
| 8416 // TODO(sievers): This could be resolved at the GL binding level, but the | 8396 // TODO(sievers): This could be resolved at the GL binding level, but the |
| 8417 // binding process is currently a bit too 'brute force'. | 8397 // binding process is currently a bit too 'brute force'. |
| 8418 if (features().use_img_for_multisampled_render_to_texture) { | 8398 if (feature_info->feature_flags().use_core_framebuffer_multisample) { |
| 8419 glRenderbufferStorageMultisampleIMG(target, samples, internal_format, width, | |
| 8420 height); | |
| 8421 } else if (features().use_core_framebuffer_multisample) { | |
| 8422 glRenderbufferStorageMultisample( | 8399 glRenderbufferStorageMultisample( |
| 8423 target, samples, internal_format, width, height); | 8400 target, samples, internal_format, width, height); |
| 8424 } else if (features().angle_framebuffer_multisample) { | 8401 } else if (feature_info->feature_flags().angle_framebuffer_multisample) { |
| 8425 // This is ES2 only. | 8402 // This is ES2 only. |
| 8426 glRenderbufferStorageMultisampleANGLE( | 8403 glRenderbufferStorageMultisampleANGLE( |
| 8427 target, samples, internal_format, width, height); | 8404 target, samples, internal_format, width, height); |
| 8428 } else { | 8405 } else { |
| 8429 glRenderbufferStorageMultisampleEXT( | 8406 glRenderbufferStorageMultisampleEXT( |
| 8430 target, samples, internal_format, width, height); | 8407 target, samples, internal_format, width, height); |
| 8431 } | 8408 } |
| 8432 } | 8409 } |
| 8433 | 8410 |
| 8434 bool GLES2DecoderImpl::RegenerateRenderbufferIfNeeded( | |
| 8435 Renderbuffer* renderbuffer) { | |
| 8436 if (!workarounds().multisample_renderbuffer_resize_emulation) { | |
| 8437 return false; | |
| 8438 } | |
| 8439 | |
| 8440 if (!renderbuffer->RegenerateAndBindBackingObjectIfNeeded()) { | |
| 8441 return false; | |
| 8442 } | |
| 8443 | |
| 8444 if (renderbuffer != state_.bound_renderbuffer.get()) { | |
| 8445 // The renderbuffer bound in the driver has changed to the new | |
| 8446 // renderbuffer->service_id(). If that isn't state_.bound_renderbuffer, | |
| 8447 // then state_.bound_renderbuffer is no longer bound in the driver. | |
| 8448 state_.bound_renderbuffer_valid = false; | |
| 8449 } | |
| 8450 | |
| 8451 return true; | |
| 8452 } | |
| 8453 | |
| 8454 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, | 8411 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, |
| 8455 GLint srcY0, | 8412 GLint srcY0, |
| 8456 GLint srcX1, | 8413 GLint srcX1, |
| 8457 GLint srcY1, | 8414 GLint srcY1, |
| 8458 GLint dstX0, | 8415 GLint dstX0, |
| 8459 GLint dstY0, | 8416 GLint dstY0, |
| 8460 GLint dstX1, | 8417 GLint dstX1, |
| 8461 GLint dstY1, | 8418 GLint dstY1, |
| 8462 GLbitfield mask, | 8419 GLbitfield mask, |
| 8463 GLenum filter) { | 8420 GLenum filter) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8524 "glRenderbufferStorageMultisampleCHROMIUM", | 8481 "glRenderbufferStorageMultisampleCHROMIUM", |
| 8525 "no renderbuffer bound"); | 8482 "no renderbuffer bound"); |
| 8526 return; | 8483 return; |
| 8527 } | 8484 } |
| 8528 | 8485 |
| 8529 if (!ValidateRenderbufferStorageMultisample( | 8486 if (!ValidateRenderbufferStorageMultisample( |
| 8530 samples, internalformat, width, height)) { | 8487 samples, internalformat, width, height)) { |
| 8531 return; | 8488 return; |
| 8532 } | 8489 } |
| 8533 | 8490 |
| 8491 EnsureRenderbufferBound(); |
| 8534 GLenum impl_format = | 8492 GLenum impl_format = |
| 8535 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( | 8493 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( |
| 8536 internalformat); | 8494 internalformat); |
| 8537 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( | 8495 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( |
| 8538 "glRenderbufferStorageMultisampleCHROMIUM"); | 8496 "glRenderbufferStorageMultisampleCHROMIUM"); |
| 8539 RenderbufferStorageMultisampleWithWorkaround(target, samples, impl_format, | 8497 RenderbufferStorageMultisampleHelper( |
| 8540 width, height); | 8498 feature_info_.get(), target, samples, impl_format, width, height); |
| 8541 GLenum error = | 8499 GLenum error = |
| 8542 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); | 8500 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); |
| 8543 if (error == GL_NO_ERROR) { | 8501 if (error == GL_NO_ERROR) { |
| 8544 if (workarounds().validate_multisample_buffer_allocation) { | 8502 if (workarounds().validate_multisample_buffer_allocation) { |
| 8545 if (!VerifyMultisampleRenderbufferIntegrity( | 8503 if (!VerifyMultisampleRenderbufferIntegrity( |
| 8546 renderbuffer->service_id(), impl_format)) { | 8504 renderbuffer->service_id(), impl_format)) { |
| 8547 LOCAL_SET_GL_ERROR( | 8505 LOCAL_SET_GL_ERROR( |
| 8548 GL_OUT_OF_MEMORY, | 8506 GL_OUT_OF_MEMORY, |
| 8549 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory"); | 8507 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory"); |
| 8550 return; | 8508 return; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 8566 "glRenderbufferStorageMultisampleEXT", | 8524 "glRenderbufferStorageMultisampleEXT", |
| 8567 "no renderbuffer bound"); | 8525 "no renderbuffer bound"); |
| 8568 return; | 8526 return; |
| 8569 } | 8527 } |
| 8570 | 8528 |
| 8571 if (!ValidateRenderbufferStorageMultisample( | 8529 if (!ValidateRenderbufferStorageMultisample( |
| 8572 samples, internalformat, width, height)) { | 8530 samples, internalformat, width, height)) { |
| 8573 return; | 8531 return; |
| 8574 } | 8532 } |
| 8575 | 8533 |
| 8534 EnsureRenderbufferBound(); |
| 8576 GLenum impl_format = | 8535 GLenum impl_format = |
| 8577 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( | 8536 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( |
| 8578 internalformat); | 8537 internalformat); |
| 8579 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT"); | 8538 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT"); |
| 8580 RenderbufferStorageMultisampleWithWorkaround(target, samples, impl_format, | 8539 if (features().use_img_for_multisampled_render_to_texture) { |
| 8581 width, height); | 8540 glRenderbufferStorageMultisampleIMG( |
| 8541 target, samples, impl_format, width, height); |
| 8542 } else { |
| 8543 glRenderbufferStorageMultisampleEXT( |
| 8544 target, samples, impl_format, width, height); |
| 8545 } |
| 8582 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT"); | 8546 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT"); |
| 8583 if (error == GL_NO_ERROR) { | 8547 if (error == GL_NO_ERROR) { |
| 8584 renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples, | 8548 renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples, |
| 8585 internalformat, width, height); | 8549 internalformat, width, height); |
| 8586 } | 8550 } |
| 8587 } | 8551 } |
| 8588 | 8552 |
| 8589 // This function validates the allocation of a multisampled renderbuffer | 8553 // This function validates the allocation of a multisampled renderbuffer |
| 8590 // by clearing it to a key color, blitting the contents to a texture, and | 8554 // by clearing it to a key color, blitting the contents to a texture, and |
| 8591 // reading back the color to ensure it matches the key. | 8555 // reading back the color to ensure it matches the key. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8715 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large"); | 8679 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large"); |
| 8716 return; | 8680 return; |
| 8717 } | 8681 } |
| 8718 | 8682 |
| 8719 if (!EnsureGPUMemoryAvailable(estimated_size)) { | 8683 if (!EnsureGPUMemoryAvailable(estimated_size)) { |
| 8720 LOCAL_SET_GL_ERROR( | 8684 LOCAL_SET_GL_ERROR( |
| 8721 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); | 8685 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); |
| 8722 return; | 8686 return; |
| 8723 } | 8687 } |
| 8724 | 8688 |
| 8689 EnsureRenderbufferBound(); |
| 8725 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage"); | 8690 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage"); |
| 8726 RenderbufferStorageMultisampleWithWorkaround( | 8691 glRenderbufferStorageEXT( |
| 8727 target, 0, | 8692 target, |
| 8728 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( | 8693 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( |
| 8729 internalformat), | 8694 internalformat), |
| 8730 width, height); | 8695 width, |
| 8696 height); |
| 8731 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage"); | 8697 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage"); |
| 8732 if (error == GL_NO_ERROR) { | 8698 if (error == GL_NO_ERROR) { |
| 8733 renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, 0, | 8699 renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, 0, |
| 8734 internalformat, width, height); | 8700 internalformat, width, height); |
| 8735 } | 8701 } |
| 8736 } | 8702 } |
| 8737 | 8703 |
| 8738 void GLES2DecoderImpl::DoLineWidth(GLfloat width) { | 8704 void GLES2DecoderImpl::DoLineWidth(GLfloat width) { |
| 8739 glLineWidth( | 8705 glLineWidth( |
| 8740 std::min(std::max(width, line_width_range_[0]), line_width_range_[1])); | 8706 std::min(std::max(width, line_width_range_[0]), line_width_range_[1])); |
| (...skipping 10997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19738 } | 19704 } |
| 19739 | 19705 |
| 19740 // Include the auto-generated part of this file. We split this because it means | 19706 // Include the auto-generated part of this file. We split this because it means |
| 19741 // we can easily edit the non-auto generated parts right here in this file | 19707 // we can easily edit the non-auto generated parts right here in this file |
| 19742 // instead of having to edit some template or the code generator. | 19708 // instead of having to edit some template or the code generator. |
| 19743 #include "base/macros.h" | 19709 #include "base/macros.h" |
| 19744 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 19710 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 19745 | 19711 |
| 19746 } // namespace gles2 | 19712 } // namespace gles2 |
| 19747 } // namespace gpu | 19713 } // namespace gpu |
| OLD | NEW |