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 <list> | 10 #include <list> |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 49 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
50 #include "gpu/command_buffer/service/shader_manager.h" | 50 #include "gpu/command_buffer/service/shader_manager.h" |
51 #include "gpu/command_buffer/service/shader_translator.h" | 51 #include "gpu/command_buffer/service/shader_translator.h" |
52 #include "gpu/command_buffer/service/shader_translator_cache.h" | 52 #include "gpu/command_buffer/service/shader_translator_cache.h" |
53 #include "gpu/command_buffer/service/stream_texture.h" | 53 #include "gpu/command_buffer/service/stream_texture.h" |
54 #include "gpu/command_buffer/service/stream_texture_manager.h" | 54 #include "gpu/command_buffer/service/stream_texture_manager.h" |
55 #include "gpu/command_buffer/service/texture_definition.h" | 55 #include "gpu/command_buffer/service/texture_definition.h" |
56 #include "gpu/command_buffer/service/texture_manager.h" | 56 #include "gpu/command_buffer/service/texture_manager.h" |
57 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 57 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
58 #include "gpu/command_buffer/service/vertex_array_manager.h" | 58 #include "gpu/command_buffer/service/vertex_array_manager.h" |
59 #include "ui/gl/async_pixel_transfer_delegate.h" | |
59 #include "ui/gl/gl_image.h" | 60 #include "ui/gl/gl_image.h" |
60 #include "ui/gl/gl_implementation.h" | 61 #include "ui/gl/gl_implementation.h" |
61 #include "ui/gl/gl_surface.h" | 62 #include "ui/gl/gl_surface.h" |
62 #if defined(OS_MACOSX) | 63 #if defined(OS_MACOSX) |
63 #include "ui/surface/io_surface_support_mac.h" | 64 #include "ui/surface/io_surface_support_mac.h" |
64 #endif | 65 #endif |
65 | 66 |
66 #if !defined(GL_DEPTH24_STENCIL8) | 67 #if !defined(GL_DEPTH24_STENCIL8) |
67 #define GL_DEPTH24_STENCIL8 0x88F0 | 68 #define GL_DEPTH24_STENCIL8 0x88F0 |
68 #endif | 69 #endif |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 } | 187 } |
187 | 188 |
188 static inline GLenum GetTexInternalFormat(GLenum internal_format) { | 189 static inline GLenum GetTexInternalFormat(GLenum internal_format) { |
189 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 190 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { |
190 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) | 191 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) |
191 return GL_RGBA8; | 192 return GL_RGBA8; |
192 } | 193 } |
193 return internal_format; | 194 return internal_format; |
194 } | 195 } |
195 | 196 |
197 // TODO(epenner): Could the above function be merged into this and removed? | |
198 static inline GLenum GetTexInternalFormat(GLenum internal_format, | |
199 GLenum format, | |
200 GLenum type) { | |
201 GLenum gl_internal_format = GetTexInternalFormat(internal_format); | |
202 | |
203 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) | |
204 return gl_internal_format; | |
205 | |
206 if (type == GL_FLOAT) { | |
207 switch (format) { | |
208 case GL_RGBA: | |
209 gl_internal_format = GL_RGBA32F_ARB; | |
210 break; | |
211 case GL_RGB: | |
212 gl_internal_format = GL_RGB32F_ARB; | |
213 break; | |
214 case GL_LUMINANCE_ALPHA: | |
215 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB; | |
216 break; | |
217 case GL_LUMINANCE: | |
218 gl_internal_format = GL_LUMINANCE32F_ARB; | |
219 break; | |
220 case GL_ALPHA: | |
221 gl_internal_format = GL_ALPHA32F_ARB; | |
222 break; | |
223 default: | |
224 NOTREACHED(); | |
225 break; | |
226 } | |
227 } else if (type == GL_HALF_FLOAT_OES) { | |
228 switch (format) { | |
229 case GL_RGBA: | |
230 gl_internal_format = GL_RGBA16F_ARB; | |
231 break; | |
232 case GL_RGB: | |
233 gl_internal_format = GL_RGB16F_ARB; | |
234 break; | |
235 case GL_LUMINANCE_ALPHA: | |
236 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB; | |
237 break; | |
238 case GL_LUMINANCE: | |
239 gl_internal_format = GL_LUMINANCE16F_ARB; | |
240 break; | |
241 case GL_ALPHA: | |
242 gl_internal_format = GL_ALPHA16F_ARB; | |
243 break; | |
244 default: | |
245 NOTREACHED(); | |
246 break; | |
247 } | |
248 } | |
249 return gl_internal_format; | |
250 } | |
251 | |
196 static void WrappedTexImage2D( | 252 static void WrappedTexImage2D( |
197 GLenum target, | 253 GLenum target, |
198 GLint level, | 254 GLint level, |
199 GLenum internal_format, | 255 GLenum internal_format, |
200 GLsizei width, | 256 GLsizei width, |
201 GLsizei height, | 257 GLsizei height, |
202 GLint border, | 258 GLint border, |
203 GLenum format, | 259 GLenum format, |
204 GLenum type, | 260 GLenum type, |
205 const void* pixels) { | 261 const void* pixels) { |
206 GLenum gl_internal_format = GetTexInternalFormat(internal_format); | |
207 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | |
208 if (type == GL_FLOAT) { | |
209 switch (format) { | |
210 case GL_RGBA: | |
211 gl_internal_format = GL_RGBA32F_ARB; | |
212 break; | |
213 case GL_RGB: | |
214 gl_internal_format = GL_RGB32F_ARB; | |
215 break; | |
216 case GL_LUMINANCE_ALPHA: | |
217 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB; | |
218 break; | |
219 case GL_LUMINANCE: | |
220 gl_internal_format = GL_LUMINANCE32F_ARB; | |
221 break; | |
222 case GL_ALPHA: | |
223 gl_internal_format = GL_ALPHA32F_ARB; | |
224 break; | |
225 default: | |
226 NOTREACHED(); | |
227 break; | |
228 } | |
229 } else if (type == GL_HALF_FLOAT_OES) { | |
230 switch (format) { | |
231 case GL_RGBA: | |
232 gl_internal_format = GL_RGBA16F_ARB; | |
233 break; | |
234 case GL_RGB: | |
235 gl_internal_format = GL_RGB16F_ARB; | |
236 break; | |
237 case GL_LUMINANCE_ALPHA: | |
238 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB; | |
239 break; | |
240 case GL_LUMINANCE: | |
241 gl_internal_format = GL_LUMINANCE16F_ARB; | |
242 break; | |
243 case GL_ALPHA: | |
244 gl_internal_format = GL_ALPHA16F_ARB; | |
245 break; | |
246 default: | |
247 NOTREACHED(); | |
248 break; | |
249 } | |
250 } | |
251 } | |
252 glTexImage2D( | 262 glTexImage2D( |
253 target, level, gl_internal_format, width, height, border, format, type, | 263 target, level, GetTexInternalFormat(internal_format, format, type), |
254 pixels); | 264 width, height, border, format, type, pixels); |
255 } | 265 } |
256 | 266 |
257 // Wrapper for glEnable/glDisable that doesn't suck. | 267 // Wrapper for glEnable/glDisable that doesn't suck. |
258 static void EnableDisable(GLenum pname, bool enable) { | 268 static void EnableDisable(GLenum pname, bool enable) { |
259 if (enable) { | 269 if (enable) { |
260 glEnable(pname); | 270 glEnable(pname); |
261 } else { | 271 } else { |
262 glDisable(pname); | 272 glDisable(pname); |
263 } | 273 } |
264 } | 274 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 const char* msg); | 555 const char* msg); |
546 virtual void SetGLErrorInvalidEnum(const char* function_name, | 556 virtual void SetGLErrorInvalidEnum(const char* function_name, |
547 GLenum value, | 557 GLenum value, |
548 const char* label); | 558 const char* label); |
549 virtual void SetResizeCallback( | 559 virtual void SetResizeCallback( |
550 const base::Callback<void(gfx::Size)>& callback) OVERRIDE; | 560 const base::Callback<void(gfx::Size)>& callback) OVERRIDE; |
551 | 561 |
552 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE; | 562 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE; |
553 | 563 |
554 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE; | 564 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE; |
565 | |
566 virtual gfx::AsyncPixelTransferDelegate* | |
567 GetAsyncPixelTransferDelegate() OVERRIDE; | |
568 virtual void SetAsyncPixelTransferDelegate( | |
569 gfx::AsyncPixelTransferDelegate* delegate) OVERRIDE; | |
570 | |
555 virtual bool GetServiceTextureId(uint32 client_texture_id, | 571 virtual bool GetServiceTextureId(uint32 client_texture_id, |
556 uint32* service_texture_id) OVERRIDE; | 572 uint32* service_texture_id) OVERRIDE; |
557 | 573 |
558 virtual uint32 GetGLError() OVERRIDE; | 574 virtual uint32 GetGLError() OVERRIDE; |
559 | 575 |
560 virtual uint32 GetTextureUploadCount() OVERRIDE; | 576 virtual uint32 GetTextureUploadCount() OVERRIDE; |
561 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; | 577 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; |
562 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; | 578 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; |
563 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; | 579 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; |
564 | 580 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 GLenum target, | 783 GLenum target, |
768 GLint level, | 784 GLint level, |
769 GLint xoffset, | 785 GLint xoffset, |
770 GLint yoffset, | 786 GLint yoffset, |
771 GLsizei width, | 787 GLsizei width, |
772 GLsizei height, | 788 GLsizei height, |
773 GLenum format, | 789 GLenum format, |
774 GLenum type, | 790 GLenum type, |
775 const void * data); | 791 const void * data); |
776 | 792 |
793 // Extra validation for async tex(Sub)Image2D. | |
794 bool ValidateAsyncTransfer( | |
795 const char* function_name, | |
796 TextureManager::TextureInfo* info, | |
797 GLenum target, | |
798 GLint level, | |
799 const void * data); | |
800 | |
777 // Wrapper for TexImageIOSurface2DCHROMIUM. | 801 // Wrapper for TexImageIOSurface2DCHROMIUM. |
778 void DoTexImageIOSurface2DCHROMIUM( | 802 void DoTexImageIOSurface2DCHROMIUM( |
779 GLenum target, | 803 GLenum target, |
780 GLsizei width, | 804 GLsizei width, |
781 GLsizei height, | 805 GLsizei height, |
782 GLuint io_surface_id, | 806 GLuint io_surface_id, |
783 GLuint plane); | 807 GLuint plane); |
784 | 808 |
785 void DoCopyTextureCHROMIUM( | 809 void DoCopyTextureCHROMIUM( |
786 GLenum target, | 810 GLenum target, |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1591 | 1615 |
1592 scoped_ptr<QueryManager> query_manager_; | 1616 scoped_ptr<QueryManager> query_manager_; |
1593 | 1617 |
1594 scoped_ptr<VertexArrayManager> vertex_array_manager_; | 1618 scoped_ptr<VertexArrayManager> vertex_array_manager_; |
1595 | 1619 |
1596 base::Callback<void(gfx::Size)> resize_callback_; | 1620 base::Callback<void(gfx::Size)> resize_callback_; |
1597 | 1621 |
1598 MsgCallback msg_callback_; | 1622 MsgCallback msg_callback_; |
1599 | 1623 |
1600 StreamTextureManager* stream_texture_manager_; | 1624 StreamTextureManager* stream_texture_manager_; |
1625 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_; | |
1601 | 1626 |
1602 // The format of the back buffer_ | 1627 // The format of the back buffer_ |
1603 GLenum back_buffer_color_format_; | 1628 GLenum back_buffer_color_format_; |
1604 bool back_buffer_has_depth_; | 1629 bool back_buffer_has_depth_; |
1605 bool back_buffer_has_stencil_; | 1630 bool back_buffer_has_stencil_; |
1606 | 1631 |
1607 // Backbuffer attachments that are currently undefined. | 1632 // Backbuffer attachments that are currently undefined. |
1608 uint32 backbuffer_needs_clear_bits_; | 1633 uint32 backbuffer_needs_clear_bits_; |
1609 | 1634 |
1610 bool teximage2d_faster_than_texsubimage2d_; | 1635 bool teximage2d_faster_than_texsubimage2d_; |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2383 DoBindFramebuffer(GL_FRAMEBUFFER, 0); | 2408 DoBindFramebuffer(GL_FRAMEBUFFER, 0); |
2384 DoBindRenderbuffer(GL_RENDERBUFFER, 0); | 2409 DoBindRenderbuffer(GL_RENDERBUFFER, 0); |
2385 | 2410 |
2386 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord | 2411 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord |
2387 // backward from the spec and this setting makes them work | 2412 // backward from the spec and this setting makes them work |
2388 // correctly. rdar://problem/11883495 | 2413 // correctly. rdar://problem/11883495 |
2389 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { | 2414 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { |
2390 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); | 2415 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); |
2391 } | 2416 } |
2392 | 2417 |
2418 // Create a delegate to perform async pixel transfers. | |
2419 async_pixel_transfer_delegate_ = | |
2420 gfx::AsyncPixelTransferDelegate::Create(context.get()); | |
2421 | |
2393 return true; | 2422 return true; |
2394 } | 2423 } |
2395 | 2424 |
2396 void GLES2DecoderImpl::UpdateCapabilities() { | 2425 void GLES2DecoderImpl::UpdateCapabilities() { |
2397 util_.set_num_compressed_texture_formats( | 2426 util_.set_num_compressed_texture_formats( |
2398 validators_->compressed_texture_format.GetValues().size()); | 2427 validators_->compressed_texture_format.GetValues().size()); |
2399 util_.set_num_shader_binary_formats( | 2428 util_.set_num_shader_binary_formats( |
2400 validators_->shader_binary_format.GetValues().size()); | 2429 validators_->shader_binary_format.GetValues().size()); |
2401 } | 2430 } |
2402 | 2431 |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2880 } | 2909 } |
2881 | 2910 |
2882 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { | 2911 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { |
2883 msg_callback_ = callback; | 2912 msg_callback_ = callback; |
2884 } | 2913 } |
2885 | 2914 |
2886 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { | 2915 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { |
2887 stream_texture_manager_ = manager; | 2916 stream_texture_manager_ = manager; |
2888 } | 2917 } |
2889 | 2918 |
2919 gfx::AsyncPixelTransferDelegate* | |
2920 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() { | |
2921 return async_pixel_transfer_delegate_.get(); | |
2922 } | |
2923 | |
2924 void GLES2DecoderImpl::SetAsyncPixelTransferDelegate( | |
2925 gfx::AsyncPixelTransferDelegate* delegate) { | |
2926 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate); | |
2927 } | |
2928 | |
2890 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, | 2929 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, |
2891 uint32* service_texture_id) { | 2930 uint32* service_texture_id) { |
2892 TextureManager::TextureInfo* texture = | 2931 TextureManager::TextureInfo* texture = |
2893 texture_manager()->GetTextureInfo(client_texture_id); | 2932 texture_manager()->GetTextureInfo(client_texture_id); |
2894 if (texture) { | 2933 if (texture) { |
2895 *service_texture_id = texture->service_id(); | 2934 *service_texture_id = texture->service_id(); |
2896 return true; | 2935 return true; |
2897 } | 2936 } |
2898 return false; | 2937 return false; |
2899 } | 2938 } |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3622 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { | 3661 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { |
3623 SetGLError(GL_INVALID_OPERATION, | 3662 SetGLError(GL_INVALID_OPERATION, |
3624 "glBindTexture", "illegal target for stream texture."); | 3663 "glBindTexture", "illegal target for stream texture."); |
3625 return; | 3664 return; |
3626 } | 3665 } |
3627 LogClientServiceForInfo(info, client_id, "glBindTexture"); | 3666 LogClientServiceForInfo(info, client_id, "glBindTexture"); |
3628 if (info->target() == 0) { | 3667 if (info->target() == 0) { |
3629 texture_manager()->SetInfoTarget(info, target); | 3668 texture_manager()->SetInfoTarget(info, target); |
3630 } | 3669 } |
3631 glBindTexture(target, info->service_id()); | 3670 glBindTexture(target, info->service_id()); |
3671 | |
3672 // Lazily bind async transfers if they have completed. | |
3673 // TODO(epenner): Should this be delayed to draw time? | |
3674 if (info->GetAsyncTransferState()) { | |
3675 gfx::AsyncTexImage2DParams tex_define_params; | |
3676 if (info->GetAsyncTransferState()->BindTransfer( | |
3677 target, &tex_define_params)) { | |
3678 DCHECK_EQ(target, tex_define_params.target); | |
3679 texture_manager()->SetLevelInfo( | |
3680 info, | |
3681 tex_define_params.target, | |
3682 tex_define_params.level, | |
3683 tex_define_params.internal_format, | |
3684 tex_define_params.width, | |
3685 tex_define_params.height, | |
3686 1, // depth | |
3687 tex_define_params.border, | |
3688 tex_define_params.format, | |
3689 tex_define_params.type, | |
3690 true); // cleared | |
3691 } | |
3692 } | |
3693 | |
3632 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; | 3694 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; |
3633 unit.bind_target = target; | 3695 unit.bind_target = target; |
3634 switch (target) { | 3696 switch (target) { |
3635 case GL_TEXTURE_2D: | 3697 case GL_TEXTURE_2D: |
3636 unit.bound_texture_2d = info; | 3698 unit.bound_texture_2d = info; |
3637 break; | 3699 break; |
3638 case GL_TEXTURE_CUBE_MAP: | 3700 case GL_TEXTURE_CUBE_MAP: |
3639 unit.bound_texture_cube_map = info; | 3701 unit.bound_texture_cube_map = info; |
3640 break; | 3702 break; |
3641 case GL_TEXTURE_EXTERNAL_OES: | 3703 case GL_TEXTURE_EXTERNAL_OES: |
(...skipping 6017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9659 SetGLError(GL_INVALID_OPERATION, | 9721 SetGLError(GL_INVALID_OPERATION, |
9660 "glTraceEndCHROMIUM", "no trace begin found"); | 9722 "glTraceEndCHROMIUM", "no trace begin found"); |
9661 return; | 9723 return; |
9662 } | 9724 } |
9663 | 9725 |
9664 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); | 9726 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); |
9665 trace->EnableEndTrace(); | 9727 trace->EnableEndTrace(); |
9666 gpu_trace_stack_.pop(); | 9728 gpu_trace_stack_.pop(); |
9667 } | 9729 } |
9668 | 9730 |
9731 bool GLES2DecoderImpl::ValidateAsyncTransfer( | |
9732 const char* function_name, | |
9733 TextureManager::TextureInfo* info, | |
9734 GLenum target, | |
9735 GLint level, | |
9736 const void * data) { | |
9737 // We only support async uploads to 2D textures for now. | |
9738 if (GL_TEXTURE_2D != target) { | |
9739 SetGLErrorInvalidEnum(function_name, target, "target"); | |
9740 return false; | |
9741 } | |
9742 // We only support uploads to level zero for now. | |
9743 if (level != 0) { | |
9744 SetGLError(GL_INVALID_VALUE, function_name, "level != 0"); | |
9745 return false; | |
9746 } | |
9747 // A transfer buffer must be bound, even for asyncTexImage2D. | |
9748 if (data == NULL) { | |
9749 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0"); | |
9750 return false; | |
9751 } | |
9752 // We only support one async transfer in progress. | |
9753 if (!info || info->AsyncTransferIsInProgress()) { | |
9754 SetGLError(GL_INVALID_OPERATION, | |
9755 function_name, "transfer already in progress"); | |
9756 return false; | |
9757 } | |
9758 return true; | |
9759 } | |
9760 | |
9669 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( | 9761 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( |
9670 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { | 9762 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { |
9671 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); | 9763 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); |
9672 | |
9673 // TODO: This is a copy of HandleTexImage2D validation. Merge | |
9674 // as much of it as possible. | |
9675 tex_image_2d_failed_ = true; | |
9676 GLenum target = static_cast<GLenum>(c.target); | 9764 GLenum target = static_cast<GLenum>(c.target); |
9677 GLint level = static_cast<GLint>(c.level); | 9765 GLint level = static_cast<GLint>(c.level); |
9678 GLint internal_format = static_cast<GLint>(c.internalformat); | 9766 GLint internal_format = static_cast<GLint>(c.internalformat); |
9679 GLsizei width = static_cast<GLsizei>(c.width); | 9767 GLsizei width = static_cast<GLsizei>(c.width); |
9680 GLsizei height = static_cast<GLsizei>(c.height); | 9768 GLsizei height = static_cast<GLsizei>(c.height); |
9681 GLint border = static_cast<GLint>(c.border); | 9769 GLint border = static_cast<GLint>(c.border); |
9682 GLenum format = static_cast<GLenum>(c.format); | 9770 GLenum format = static_cast<GLenum>(c.format); |
9683 GLenum type = static_cast<GLenum>(c.type); | 9771 GLenum type = static_cast<GLenum>(c.type); |
9684 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); | 9772 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); |
9685 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); | 9773 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); |
9686 uint32 pixels_size; | 9774 uint32 pixels_size; |
9775 | |
9776 // TODO(epenner): Move this and copies of this memory validation | |
9777 // into ValidateTexImage2D step. | |
9687 if (!GLES2Util::ComputeImageDataSizes( | 9778 if (!GLES2Util::ComputeImageDataSizes( |
9688 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, | 9779 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, |
9689 NULL)) { | 9780 NULL)) { |
9690 return error::kOutOfBounds; | 9781 return error::kOutOfBounds; |
9691 } | 9782 } |
9692 const void* pixels = NULL; | 9783 const void* pixels = NULL; |
9693 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { | 9784 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
9694 pixels = GetSharedMemoryAs<const void*>( | 9785 pixels = GetSharedMemoryAs<const void*>( |
9695 pixels_shm_id, pixels_shm_offset, pixels_size); | 9786 pixels_shm_id, pixels_shm_offset, pixels_size); |
9696 if (!pixels) { | 9787 if (!pixels) { |
9697 return error::kOutOfBounds; | 9788 return error::kOutOfBounds; |
9698 } | 9789 } |
9699 } | 9790 } |
9700 | 9791 |
9701 // TODO(epenner): Do this via an async task. | 9792 // All the normal glTexSubImage2D validation. |
9702 DoTexImage2D( | 9793 if (!ValidateTexImage2D("glAsyncTexImage2D", target, level, internal_format, |
9703 target, level, internal_format, width, height, border, format, type, | 9794 width, height, border, format, type, pixels, pixels_size)) { |
9704 pixels, pixels_size); | 9795 return error::kNoError; |
9796 } | |
9797 | |
9798 // Extra async validation. | |
9799 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
9800 if (!ValidateAsyncTransfer("glAsyncTexImage2D", info, target, level, pixels)) | |
9801 return error::kNoError; | |
9802 | |
9803 // Don't allow async redefinition of a textures. | |
9804 if (info->IsDefined()) { | |
9805 SetGLError(GL_INVALID_OPERATION, "glAsyncTexImage2D", "already defined"); | |
9806 return error::kNoError; | |
9807 } | |
9808 | |
9809 if (info->IsAttachedToFramebuffer()) { | |
greggman
2012/12/13 06:29:21
Just to document our conversation
This code marks
| |
9810 clear_state_dirty_ = true; | |
9811 // TODO(gman): If textures tracked which framebuffers they were attached to | |
9812 // we could just mark those framebuffers as not complete. | |
9813 framebuffer_manager()->IncFramebufferStateChangeCount(); | |
9814 } | |
9815 | |
9816 // We know the memory/size is safe, so get the real shared memory since | |
9817 // it might need to be duped to prevent use-after-free of the memory. | |
9818 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | |
9819 base::SharedMemory* shared_memory = buffer.shared_memory; | |
9820 uint32 shm_size = buffer.size; | |
9821 uint32 shm_data_offset = c.pixels_shm_offset; | |
9822 uint32 shm_data_size = pixels_size; | |
9823 | |
9824 // Set up the async state if needed, and make the texture | |
9825 // immutable so the async state stays valid. The level info | |
9826 // is set up lazily when the transfer completes. | |
9827 DCHECK(!info->GetAsyncTransferState()); | |
9828 info->SetAsyncTransferState( | |
9829 async_pixel_transfer_delegate_-> | |
9830 CreatePixelTransferState(info->service_id())); | |
9831 info->SetImmutable(true); | |
9832 | |
9833 // Issue the async call and set up the texture. | |
9834 GLenum gl_internal_format = | |
9835 GetTexInternalFormat(internal_format, format, type); | |
9836 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format, | |
9837 width, height, border, format, type}; | |
9838 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, | |
9839 shm_data_offset, shm_data_size}; | |
9840 async_pixel_transfer_delegate_->AsyncTexImage2D( | |
9841 info->GetAsyncTransferState(), tex_params, mem_params); | |
9705 return error::kNoError; | 9842 return error::kNoError; |
9706 } | 9843 } |
9707 | 9844 |
9708 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( | 9845 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( |
9709 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { | 9846 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { |
9710 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); | 9847 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); |
9711 | |
9712 // TODO: This is a copy of HandleTexSubImage2D validation. Merge | |
9713 // as much of it as possible. | |
9714 GLenum target = static_cast<GLenum>(c.target); | 9848 GLenum target = static_cast<GLenum>(c.target); |
9715 GLint level = static_cast<GLint>(c.level); | 9849 GLint level = static_cast<GLint>(c.level); |
9716 GLint xoffset = static_cast<GLint>(c.xoffset); | 9850 GLint xoffset = static_cast<GLint>(c.xoffset); |
9717 GLint yoffset = static_cast<GLint>(c.yoffset); | 9851 GLint yoffset = static_cast<GLint>(c.yoffset); |
9718 GLsizei width = static_cast<GLsizei>(c.width); | 9852 GLsizei width = static_cast<GLsizei>(c.width); |
9719 GLsizei height = static_cast<GLsizei>(c.height); | 9853 GLsizei height = static_cast<GLsizei>(c.height); |
9720 GLenum format = static_cast<GLenum>(c.format); | 9854 GLenum format = static_cast<GLenum>(c.format); |
9721 GLenum type = static_cast<GLenum>(c.type); | 9855 GLenum type = static_cast<GLenum>(c.type); |
9856 | |
9857 // TODO(epenner): Move this and copies of this memory validation | |
9858 // into ValidateTexSubImage2D step. | |
9722 uint32 data_size; | 9859 uint32 data_size; |
9723 if (!GLES2Util::ComputeImageDataSizes( | 9860 if (!GLES2Util::ComputeImageDataSizes( |
9724 width, height, format, type, state_.unpack_alignment, &data_size, | 9861 width, height, format, type, state_.unpack_alignment, &data_size, |
9725 NULL, NULL)) { | 9862 NULL, NULL)) { |
9726 return error::kOutOfBounds; | 9863 return error::kOutOfBounds; |
9727 } | 9864 } |
9728 const void* pixels = GetSharedMemoryAs<const void*>( | 9865 const void* pixels = GetSharedMemoryAs<const void*>( |
9729 c.data_shm_id, c.data_shm_offset, data_size); | 9866 c.data_shm_id, c.data_shm_offset, data_size); |
9730 if (pixels == NULL) { | 9867 |
9731 return error::kOutOfBounds; | 9868 // All the normal glTexSubImage2D validation. |
9869 error::Error error = error::kNoError; | |
9870 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2D", target, level, | |
9871 xoffset, yoffset, width, height, format, type, pixels)) { | |
9872 return error; | |
9732 } | 9873 } |
9733 | 9874 |
9734 // TODO(epenner): Do this via an async task. | 9875 // Extra async validation. |
9735 return DoTexSubImage2D( | 9876 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
9736 target, level, xoffset, yoffset, width, height, format, type, pixels); | 9877 if (!ValidateAsyncTransfer( |
9878 "glAsyncTexSubImage2D", info, target, level, pixels)) | |
9879 return error::kNoError; | |
9880 | |
9881 // Guarantee async textures are always 'cleared' as follows: | |
9882 // - AsyncTexImage2D can not redefine an existing texture | |
9883 // - AsyncTexImage2D must initialize the entire image via non-null buffer. | |
9884 // - AsyncTexSubImage2D clears synchronously if not already cleared. | |
9885 // - Textures become immutable after an async call. | |
9886 // This way we know in all cases that an async texture is always clear. | |
9887 if (!info->SafeToRenderFrom()) { | |
9888 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | |
9889 SetGLError( | |
9890 GL_OUT_OF_MEMORY, "glAsyncTexSubImage2D", "dimensions too big"); | |
9891 return error::kNoError; | |
9892 } | |
9893 } | |
9894 | |
9895 // We know the memory/size is safe, so get the real shared memory since | |
9896 // it might need to be duped to prevent use-after-free of the memory. | |
9897 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id); | |
9898 base::SharedMemory* shared_memory = buffer.shared_memory; | |
9899 uint32 shm_size = buffer.size; | |
9900 uint32 shm_data_offset = c.data_shm_offset; | |
9901 uint32 shm_data_size = data_size; | |
9902 | |
9903 if (!info->GetAsyncTransferState()) { | |
9904 // Set up the async state if needed, and make the texture | |
9905 // immutable so the async state stays valid. | |
9906 info->SetAsyncTransferState( | |
9907 async_pixel_transfer_delegate_-> | |
9908 CreatePixelTransferState(info->service_id())); | |
9909 info->SetImmutable(true); | |
9910 } | |
9911 | |
9912 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset, | |
9913 width, height, format, type}; | |
9914 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, | |
9915 shm_data_offset, shm_data_size}; | |
9916 async_pixel_transfer_delegate_->AsyncTexSubImage2D( | |
9917 info->GetAsyncTransferState(), tex_params, mem_params); | |
9918 return error::kNoError; | |
9737 } | 9919 } |
9738 | 9920 |
9739 // Include the auto-generated part of this file. We split this because it means | 9921 // Include the auto-generated part of this file. We split this because it means |
9740 // we can easily edit the non-auto generated parts right here in this file | 9922 // we can easily edit the non-auto generated parts right here in this file |
9741 // instead of having to edit some template or the code generator. | 9923 // instead of having to edit some template or the code generator. |
9742 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9924 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
9743 | 9925 |
9744 } // namespace gles2 | 9926 } // namespace gles2 |
9745 } // namespace gpu | 9927 } // namespace gpu |
OLD | NEW |