Chromium Code Reviews| 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2714 last_id = 0; | 2743 last_id = 0; |
| 2715 } | 2744 } |
| 2716 | 2745 |
| 2717 glBindTexture(GL_TEXTURE_2D, last_id); | 2746 glBindTexture(GL_TEXTURE_2D, last_id); |
| 2718 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); | 2747 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); |
| 2719 } | 2748 } |
| 2720 | 2749 |
| 2721 bool GLES2DecoderImpl::CheckFramebufferValid( | 2750 bool GLES2DecoderImpl::CheckFramebufferValid( |
| 2722 FramebufferManager::FramebufferInfo* framebuffer, | 2751 FramebufferManager::FramebufferInfo* framebuffer, |
| 2723 GLenum target, const char* func_name) { | 2752 GLenum target, const char* func_name) { |
| 2753 | |
| 2754 // As this occurs before every draw, take this opportunity to | |
| 2755 // bind any unbound async pixel transfers to their textures. | |
| 2756 // TODO(epenner): Is there a better place to do this? Transfers | |
|
greggman
2012/12/14 06:08:06
This seems like it really needs to be in DoCommand
epenner
2012/12/14 21:01:34
Does DoCommand happen at every GL command? It only
| |
| 2757 // are marked as complete on the main thread, so we only need | |
| 2758 // to process them once in a given main-thread task. | |
| 2759 bool frame_buffer_dirty = false; | |
| 2760 bool texture_dirty = false; | |
| 2761 GetContextGroup()->texture_manager()->BindFinishedAsyncPixelTransfers( | |
|
greggman
2012/12/14 06:08:06
you can just use
texture_manager()->BindFinished.
epenner
2012/12/14 21:01:34
Done.
| |
| 2762 &texture_dirty, &frame_buffer_dirty); | |
| 2763 // Texture unit zero might be stomped. | |
| 2764 if (texture_dirty) | |
| 2765 RestoreCurrentTexture2DBindings(); | |
| 2766 // A texture attached to frame-buffer might have changed size. | |
| 2767 if (frame_buffer_dirty) { | |
| 2768 clear_state_dirty_ = true; | |
| 2769 // TODO(gman): If textures tracked which framebuffers they were attached to | |
| 2770 // we could just mark those framebuffers as not complete. | |
| 2771 framebuffer_manager()->IncFramebufferStateChangeCount(); | |
| 2772 } | |
| 2773 | |
| 2724 if (!framebuffer) { | 2774 if (!framebuffer) { |
| 2725 if (backbuffer_needs_clear_bits_) { | 2775 if (backbuffer_needs_clear_bits_) { |
| 2726 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( | 2776 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( |
| 2727 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); | 2777 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); |
| 2728 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 2778 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| 2729 glClearStencil(0); | 2779 glClearStencil(0); |
| 2730 glStencilMask(-1); | 2780 glStencilMask(-1); |
| 2731 glClearDepth(1.0f); | 2781 glClearDepth(1.0f); |
| 2732 glDepthMask(true); | 2782 glDepthMask(true); |
| 2733 glDisable(GL_SCISSOR_TEST); | 2783 glDisable(GL_SCISSOR_TEST); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2880 } | 2930 } |
| 2881 | 2931 |
| 2882 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { | 2932 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { |
| 2883 msg_callback_ = callback; | 2933 msg_callback_ = callback; |
| 2884 } | 2934 } |
| 2885 | 2935 |
| 2886 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { | 2936 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { |
| 2887 stream_texture_manager_ = manager; | 2937 stream_texture_manager_ = manager; |
| 2888 } | 2938 } |
| 2889 | 2939 |
| 2940 gfx::AsyncPixelTransferDelegate* | |
| 2941 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() { | |
| 2942 return async_pixel_transfer_delegate_.get(); | |
| 2943 } | |
| 2944 | |
| 2945 void GLES2DecoderImpl::SetAsyncPixelTransferDelegate( | |
| 2946 gfx::AsyncPixelTransferDelegate* delegate) { | |
| 2947 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate); | |
| 2948 } | |
| 2949 | |
| 2890 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, | 2950 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, |
| 2891 uint32* service_texture_id) { | 2951 uint32* service_texture_id) { |
| 2892 TextureManager::TextureInfo* texture = | 2952 TextureManager::TextureInfo* texture = |
| 2893 texture_manager()->GetTextureInfo(client_texture_id); | 2953 texture_manager()->GetTextureInfo(client_texture_id); |
| 2894 if (texture) { | 2954 if (texture) { |
| 2895 *service_texture_id = texture->service_id(); | 2955 *service_texture_id = texture->service_id(); |
| 2896 return true; | 2956 return true; |
| 2897 } | 2957 } |
| 2898 return false; | 2958 return false; |
| 2899 } | 2959 } |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3622 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { | 3682 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { |
| 3623 SetGLError(GL_INVALID_OPERATION, | 3683 SetGLError(GL_INVALID_OPERATION, |
| 3624 "glBindTexture", "illegal target for stream texture."); | 3684 "glBindTexture", "illegal target for stream texture."); |
| 3625 return; | 3685 return; |
| 3626 } | 3686 } |
| 3627 LogClientServiceForInfo(info, client_id, "glBindTexture"); | 3687 LogClientServiceForInfo(info, client_id, "glBindTexture"); |
| 3628 if (info->target() == 0) { | 3688 if (info->target() == 0) { |
| 3629 texture_manager()->SetInfoTarget(info, target); | 3689 texture_manager()->SetInfoTarget(info, target); |
| 3630 } | 3690 } |
| 3631 glBindTexture(target, info->service_id()); | 3691 glBindTexture(target, info->service_id()); |
| 3692 | |
| 3632 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; | 3693 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; |
| 3633 unit.bind_target = target; | 3694 unit.bind_target = target; |
| 3634 switch (target) { | 3695 switch (target) { |
| 3635 case GL_TEXTURE_2D: | 3696 case GL_TEXTURE_2D: |
| 3636 unit.bound_texture_2d = info; | 3697 unit.bound_texture_2d = info; |
| 3637 break; | 3698 break; |
| 3638 case GL_TEXTURE_CUBE_MAP: | 3699 case GL_TEXTURE_CUBE_MAP: |
| 3639 unit.bound_texture_cube_map = info; | 3700 unit.bound_texture_cube_map = info; |
| 3640 break; | 3701 break; |
| 3641 case GL_TEXTURE_EXTERNAL_OES: | 3702 case GL_TEXTURE_EXTERNAL_OES: |
| (...skipping 6017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9659 SetGLError(GL_INVALID_OPERATION, | 9720 SetGLError(GL_INVALID_OPERATION, |
| 9660 "glTraceEndCHROMIUM", "no trace begin found"); | 9721 "glTraceEndCHROMIUM", "no trace begin found"); |
| 9661 return; | 9722 return; |
| 9662 } | 9723 } |
| 9663 | 9724 |
| 9664 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); | 9725 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); |
| 9665 trace->EnableEndTrace(); | 9726 trace->EnableEndTrace(); |
| 9666 gpu_trace_stack_.pop(); | 9727 gpu_trace_stack_.pop(); |
| 9667 } | 9728 } |
| 9668 | 9729 |
| 9730 bool GLES2DecoderImpl::ValidateAsyncTransfer( | |
| 9731 const char* function_name, | |
| 9732 TextureManager::TextureInfo* info, | |
| 9733 GLenum target, | |
| 9734 GLint level, | |
| 9735 const void * data) { | |
| 9736 // We only support async uploads to 2D textures for now. | |
| 9737 if (GL_TEXTURE_2D != target) { | |
| 9738 SetGLErrorInvalidEnum(function_name, target, "target"); | |
| 9739 return false; | |
| 9740 } | |
| 9741 // We only support uploads to level zero for now. | |
| 9742 if (level != 0) { | |
| 9743 SetGLError(GL_INVALID_VALUE, function_name, "level != 0"); | |
| 9744 return false; | |
| 9745 } | |
| 9746 // A transfer buffer must be bound, even for asyncTexImage2D. | |
| 9747 if (data == NULL) { | |
| 9748 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0"); | |
| 9749 return false; | |
| 9750 } | |
| 9751 // We only support one async transfer in progress. | |
| 9752 if (!info || info->AsyncTransferIsInProgress()) { | |
| 9753 SetGLError(GL_INVALID_OPERATION, | |
| 9754 function_name, "transfer already in progress"); | |
| 9755 return false; | |
| 9756 } | |
| 9757 return true; | |
| 9758 } | |
| 9759 | |
| 9669 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( | 9760 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( |
| 9670 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { | 9761 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { |
| 9671 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); | 9762 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); | 9763 GLenum target = static_cast<GLenum>(c.target); |
| 9677 GLint level = static_cast<GLint>(c.level); | 9764 GLint level = static_cast<GLint>(c.level); |
| 9678 GLint internal_format = static_cast<GLint>(c.internalformat); | 9765 GLint internal_format = static_cast<GLint>(c.internalformat); |
| 9679 GLsizei width = static_cast<GLsizei>(c.width); | 9766 GLsizei width = static_cast<GLsizei>(c.width); |
| 9680 GLsizei height = static_cast<GLsizei>(c.height); | 9767 GLsizei height = static_cast<GLsizei>(c.height); |
| 9681 GLint border = static_cast<GLint>(c.border); | 9768 GLint border = static_cast<GLint>(c.border); |
| 9682 GLenum format = static_cast<GLenum>(c.format); | 9769 GLenum format = static_cast<GLenum>(c.format); |
| 9683 GLenum type = static_cast<GLenum>(c.type); | 9770 GLenum type = static_cast<GLenum>(c.type); |
| 9684 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); | 9771 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); |
| 9685 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); | 9772 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); |
| 9686 uint32 pixels_size; | 9773 uint32 pixels_size; |
| 9774 | |
| 9775 // TODO(epenner): Move this and copies of this memory validation | |
| 9776 // into ValidateTexImage2D step. | |
| 9687 if (!GLES2Util::ComputeImageDataSizes( | 9777 if (!GLES2Util::ComputeImageDataSizes( |
| 9688 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, | 9778 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, |
| 9689 NULL)) { | 9779 NULL)) { |
| 9690 return error::kOutOfBounds; | 9780 return error::kOutOfBounds; |
| 9691 } | 9781 } |
| 9692 const void* pixels = NULL; | 9782 const void* pixels = NULL; |
| 9693 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { | 9783 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| 9694 pixels = GetSharedMemoryAs<const void*>( | 9784 pixels = GetSharedMemoryAs<const void*>( |
| 9695 pixels_shm_id, pixels_shm_offset, pixels_size); | 9785 pixels_shm_id, pixels_shm_offset, pixels_size); |
| 9696 if (!pixels) { | 9786 if (!pixels) { |
| 9697 return error::kOutOfBounds; | 9787 return error::kOutOfBounds; |
| 9698 } | 9788 } |
| 9699 } | 9789 } |
| 9700 | 9790 |
| 9701 // TODO(epenner): Do this via an async task. | 9791 // All the normal glTexSubImage2D validation. |
| 9702 DoTexImage2D( | 9792 if (!ValidateTexImage2D("glAsyncTexImage2D", target, level, internal_format, |
|
greggman
2012/12/14 06:08:06
s/glAsyncTexImage2D/glAsyncTexImage2DCHROMIUM/
s/g
epenner
2012/12/14 21:01:34
Done.
| |
| 9703 target, level, internal_format, width, height, border, format, type, | 9793 width, height, border, format, type, pixels, pixels_size)) { |
| 9704 pixels, pixels_size); | 9794 return error::kNoError; |
| 9795 } | |
| 9796 | |
| 9797 // Extra async validation. | |
| 9798 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
| 9799 if (!ValidateAsyncTransfer("glAsyncTexImage2D", info, target, level, pixels)) | |
| 9800 return error::kNoError; | |
| 9801 | |
| 9802 // Don't allow async redefinition of a textures. | |
| 9803 if (info->IsDefined()) { | |
| 9804 SetGLError(GL_INVALID_OPERATION, "glAsyncTexImage2D", "already defined"); | |
| 9805 return error::kNoError; | |
| 9806 } | |
| 9807 | |
| 9808 // We know the memory/size is safe, so get the real shared memory since | |
| 9809 // it might need to be duped to prevent use-after-free of the memory. | |
| 9810 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | |
| 9811 base::SharedMemory* shared_memory = buffer.shared_memory; | |
| 9812 uint32 shm_size = buffer.size; | |
| 9813 uint32 shm_data_offset = c.pixels_shm_offset; | |
| 9814 uint32 shm_data_size = pixels_size; | |
| 9815 | |
| 9816 // Set up the async state if needed, and make the texture | |
| 9817 // immutable so the async state stays valid. The level info | |
| 9818 // is set up lazily when the transfer completes. | |
| 9819 DCHECK(!info->GetAsyncTransferState()); | |
| 9820 info->SetAsyncTransferState( | |
| 9821 async_pixel_transfer_delegate_-> | |
| 9822 CreatePixelTransferState(info->service_id())); | |
| 9823 info->SetImmutable(true); | |
| 9824 | |
| 9825 // Issue the async call and set up the texture. | |
| 9826 GLenum gl_internal_format = | |
| 9827 GetTexInternalFormat(internal_format, format, type); | |
| 9828 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format, | |
| 9829 width, height, border, format, type}; | |
| 9830 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, | |
| 9831 shm_data_offset, shm_data_size}; | |
| 9832 | |
| 9833 // Add a pending transfer to the texture manager, which will bind the | |
| 9834 // transfer data to the texture and set the level info at the same time, | |
| 9835 // after the the transfer is complete. | |
| 9836 GetContextGroup()->texture_manager()->AddPendingAsyncPixelTransfer( | |
|
greggman
2012/12/14 06:08:06
GetConextGroup()-> not needed?
epenner
2012/12/14 21:01:34
Done.
| |
| 9837 info->GetAsyncTransferState()->AsWeakPtr(), info); | |
| 9838 | |
| 9839 async_pixel_transfer_delegate_->AsyncTexImage2D( | |
| 9840 info->GetAsyncTransferState(), tex_params, mem_params); | |
| 9705 return error::kNoError; | 9841 return error::kNoError; |
| 9706 } | 9842 } |
| 9707 | 9843 |
| 9708 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( | 9844 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( |
| 9709 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { | 9845 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { |
| 9710 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); | 9846 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); | 9847 GLenum target = static_cast<GLenum>(c.target); |
| 9715 GLint level = static_cast<GLint>(c.level); | 9848 GLint level = static_cast<GLint>(c.level); |
| 9716 GLint xoffset = static_cast<GLint>(c.xoffset); | 9849 GLint xoffset = static_cast<GLint>(c.xoffset); |
| 9717 GLint yoffset = static_cast<GLint>(c.yoffset); | 9850 GLint yoffset = static_cast<GLint>(c.yoffset); |
| 9718 GLsizei width = static_cast<GLsizei>(c.width); | 9851 GLsizei width = static_cast<GLsizei>(c.width); |
| 9719 GLsizei height = static_cast<GLsizei>(c.height); | 9852 GLsizei height = static_cast<GLsizei>(c.height); |
| 9720 GLenum format = static_cast<GLenum>(c.format); | 9853 GLenum format = static_cast<GLenum>(c.format); |
| 9721 GLenum type = static_cast<GLenum>(c.type); | 9854 GLenum type = static_cast<GLenum>(c.type); |
| 9855 | |
| 9856 // TODO(epenner): Move this and copies of this memory validation | |
| 9857 // into ValidateTexSubImage2D step. | |
| 9722 uint32 data_size; | 9858 uint32 data_size; |
| 9723 if (!GLES2Util::ComputeImageDataSizes( | 9859 if (!GLES2Util::ComputeImageDataSizes( |
| 9724 width, height, format, type, state_.unpack_alignment, &data_size, | 9860 width, height, format, type, state_.unpack_alignment, &data_size, |
| 9725 NULL, NULL)) { | 9861 NULL, NULL)) { |
| 9726 return error::kOutOfBounds; | 9862 return error::kOutOfBounds; |
| 9727 } | 9863 } |
| 9728 const void* pixels = GetSharedMemoryAs<const void*>( | 9864 const void* pixels = GetSharedMemoryAs<const void*>( |
| 9729 c.data_shm_id, c.data_shm_offset, data_size); | 9865 c.data_shm_id, c.data_shm_offset, data_size); |
| 9730 if (pixels == NULL) { | 9866 |
| 9731 return error::kOutOfBounds; | 9867 // All the normal glTexSubImage2D validation. |
| 9868 error::Error error = error::kNoError; | |
| 9869 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2D", target, level, | |
| 9870 xoffset, yoffset, width, height, format, type, pixels)) { | |
| 9871 return error; | |
| 9732 } | 9872 } |
| 9733 | 9873 |
| 9734 // TODO(epenner): Do this via an async task. | 9874 // Extra async validation. |
| 9735 return DoTexSubImage2D( | 9875 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| 9736 target, level, xoffset, yoffset, width, height, format, type, pixels); | 9876 if (!ValidateAsyncTransfer( |
| 9877 "glAsyncTexSubImage2D", info, target, level, pixels)) | |
| 9878 return error::kNoError; | |
| 9879 | |
| 9880 // Guarantee async textures are always 'cleared' as follows: | |
| 9881 // - AsyncTexImage2D can not redefine an existing texture | |
| 9882 // - AsyncTexImage2D must initialize the entire image via non-null buffer. | |
| 9883 // - AsyncTexSubImage2D clears synchronously if not already cleared. | |
| 9884 // - Textures become immutable after an async call. | |
| 9885 // This way we know in all cases that an async texture is always clear. | |
| 9886 if (!info->SafeToRenderFrom()) { | |
| 9887 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | |
| 9888 SetGLError( | |
| 9889 GL_OUT_OF_MEMORY, "glAsyncTexSubImage2D", "dimensions too big"); | |
| 9890 return error::kNoError; | |
| 9891 } | |
| 9892 } | |
| 9893 | |
| 9894 // We know the memory/size is safe, so get the real shared memory since | |
| 9895 // it might need to be duped to prevent use-after-free of the memory. | |
| 9896 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id); | |
| 9897 base::SharedMemory* shared_memory = buffer.shared_memory; | |
| 9898 uint32 shm_size = buffer.size; | |
| 9899 uint32 shm_data_offset = c.data_shm_offset; | |
| 9900 uint32 shm_data_size = data_size; | |
| 9901 | |
| 9902 if (!info->GetAsyncTransferState()) { | |
| 9903 // Set up the async state if needed, and make the texture | |
| 9904 // immutable so the async state stays valid. | |
| 9905 info->SetAsyncTransferState( | |
| 9906 async_pixel_transfer_delegate_-> | |
| 9907 CreatePixelTransferState(info->service_id())); | |
| 9908 info->SetImmutable(true); | |
| 9909 } | |
| 9910 | |
| 9911 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset, | |
| 9912 width, height, format, type}; | |
| 9913 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, | |
| 9914 shm_data_offset, shm_data_size}; | |
| 9915 async_pixel_transfer_delegate_->AsyncTexSubImage2D( | |
| 9916 info->GetAsyncTransferState(), tex_params, mem_params); | |
| 9917 return error::kNoError; | |
| 9737 } | 9918 } |
| 9738 | 9919 |
| 9739 // Include the auto-generated part of this file. We split this because it means | 9920 // 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 | 9921 // 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. | 9922 // instead of having to edit some template or the code generator. |
| 9742 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9923 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 9743 | 9924 |
| 9744 } // namespace gles2 | 9925 } // namespace gles2 |
| 9745 } // namespace gpu | 9926 } // namespace gpu |
| OLD | NEW |