Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 11428140: gpu: Add async pixel transfer interface, stub and tests. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Address Feedback. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2407 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2383 DoBindRenderbuffer(GL_RENDERBUFFER, 0); 2408 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2384 2409
2385 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord 2410 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord
2386 // backward from the spec and this setting makes them work 2411 // backward from the spec and this setting makes them work
2387 // correctly. rdar://problem/11883495 2412 // correctly. rdar://problem/11883495
2388 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { 2413 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
2389 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 2414 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2390 } 2415 }
2391 2416
2417 // Create a delegate to perform async pixel transfers.
2418 async_pixel_transfer_delegate_ =
2419 gfx::AsyncPixelTransferDelegate::Create(context.get());
2420
2392 return true; 2421 return true;
2393 } 2422 }
2394 2423
2395 void GLES2DecoderImpl::UpdateCapabilities() { 2424 void GLES2DecoderImpl::UpdateCapabilities() {
2396 util_.set_num_compressed_texture_formats( 2425 util_.set_num_compressed_texture_formats(
2397 validators_->compressed_texture_format.GetValues().size()); 2426 validators_->compressed_texture_format.GetValues().size());
2398 util_.set_num_shader_binary_formats( 2427 util_.set_num_shader_binary_formats(
2399 validators_->shader_binary_format.GetValues().size()); 2428 validators_->shader_binary_format.GetValues().size());
2400 } 2429 }
2401 2430
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2649 2678
2650 bool GLES2DecoderImpl::MakeCurrent() { 2679 bool GLES2DecoderImpl::MakeCurrent() {
2651 if (!context_.get() || !context_->MakeCurrent(surface_.get())) 2680 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2652 return false; 2681 return false;
2653 2682
2654 if (WasContextLost()) { 2683 if (WasContextLost()) {
2655 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 2684 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
2656 return false; 2685 return false;
2657 } 2686 }
2658 2687
2688 // TODO(epenner): Is there a better place to do this? Transfers
2689 // can complete any time we yield the main thread. So we *must*
2690 // process transfers after any such yield, before resuming.
2691 bool frame_buffer_dirty = false;
2692 bool texture_dirty = false;
2693 texture_manager()->BindFinishedAsyncPixelTransfers(
2694 &texture_dirty, &frame_buffer_dirty);
2695 // Texture unit zero might be stomped.
2696 if (texture_dirty)
2697 RestoreCurrentTexture2DBindings();
2698 // A texture attached to frame-buffer might have changed size.
2699 if (frame_buffer_dirty) {
2700 clear_state_dirty_ = true;
2701 // TODO(gman): If textures tracked which framebuffers they were attached to
2702 // we could just mark those framebuffers as not complete.
2703 framebuffer_manager()->IncFramebufferStateChangeCount();
2704 }
2705
2659 return true; 2706 return true;
2660 } 2707 }
2661 2708
2662 void GLES2DecoderImpl::ReleaseCurrent() { 2709 void GLES2DecoderImpl::ReleaseCurrent() {
2663 if (context_.get()) 2710 if (context_.get())
2664 context_->ReleaseCurrent(surface_.get()); 2711 context_->ReleaseCurrent(surface_.get());
2665 } 2712 }
2666 2713
2667 void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { 2714 void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
2668 RenderbufferManager::RenderbufferInfo* renderbuffer = 2715 RenderbufferManager::RenderbufferInfo* renderbuffer =
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 } 2926 }
2880 2927
2881 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { 2928 void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) {
2882 msg_callback_ = callback; 2929 msg_callback_ = callback;
2883 } 2930 }
2884 2931
2885 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { 2932 void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
2886 stream_texture_manager_ = manager; 2933 stream_texture_manager_ = manager;
2887 } 2934 }
2888 2935
2936 gfx::AsyncPixelTransferDelegate*
2937 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
2938 return async_pixel_transfer_delegate_.get();
2939 }
2940
2941 void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
2942 gfx::AsyncPixelTransferDelegate* delegate) {
2943 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
2944 }
2945
2889 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, 2946 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
2890 uint32* service_texture_id) { 2947 uint32* service_texture_id) {
2891 TextureManager::TextureInfo* texture = 2948 TextureManager::TextureInfo* texture =
2892 texture_manager()->GetTextureInfo(client_texture_id); 2949 texture_manager()->GetTextureInfo(client_texture_id);
2893 if (texture) { 2950 if (texture) {
2894 *service_texture_id = texture->service_id(); 2951 *service_texture_id = texture->service_id();
2895 return true; 2952 return true;
2896 } 2953 }
2897 return false; 2954 return false;
2898 } 2955 }
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
3621 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { 3678 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
3622 SetGLError(GL_INVALID_OPERATION, 3679 SetGLError(GL_INVALID_OPERATION,
3623 "glBindTexture", "illegal target for stream texture."); 3680 "glBindTexture", "illegal target for stream texture.");
3624 return; 3681 return;
3625 } 3682 }
3626 LogClientServiceForInfo(info, client_id, "glBindTexture"); 3683 LogClientServiceForInfo(info, client_id, "glBindTexture");
3627 if (info->target() == 0) { 3684 if (info->target() == 0) {
3628 texture_manager()->SetInfoTarget(info, target); 3685 texture_manager()->SetInfoTarget(info, target);
3629 } 3686 }
3630 glBindTexture(target, info->service_id()); 3687 glBindTexture(target, info->service_id());
3688
3631 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3689 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
3632 unit.bind_target = target; 3690 unit.bind_target = target;
3633 switch (target) { 3691 switch (target) {
3634 case GL_TEXTURE_2D: 3692 case GL_TEXTURE_2D:
3635 unit.bound_texture_2d = info; 3693 unit.bound_texture_2d = info;
3636 break; 3694 break;
3637 case GL_TEXTURE_CUBE_MAP: 3695 case GL_TEXTURE_CUBE_MAP:
3638 unit.bound_texture_cube_map = info; 3696 unit.bound_texture_cube_map = info;
3639 break; 3697 break;
3640 case GL_TEXTURE_EXTERNAL_OES: 3698 case GL_TEXTURE_EXTERNAL_OES:
(...skipping 4267 matching lines...) Expand 10 before | Expand all | Expand 10 after
7908 } 7966 }
7909 GLenum type = 0; 7967 GLenum type = 0;
7910 GLenum format = 0; 7968 GLenum format = 0;
7911 if (!info->GetLevelType(target, level, &type, &format) || 7969 if (!info->GetLevelType(target, level, &type, &format) ||
7912 !info->ValidForTexture( 7970 !info->ValidForTexture(
7913 target, level, xoffset, yoffset, width, height, format, type)) { 7971 target, level, xoffset, yoffset, width, height, format, type)) {
7914 SetGLError(GL_INVALID_VALUE, 7972 SetGLError(GL_INVALID_VALUE,
7915 "glCopyTexSubImage2D", "bad dimensions."); 7973 "glCopyTexSubImage2D", "bad dimensions.");
7916 return; 7974 return;
7917 } 7975 }
7976 if (info->AsyncTransferIsInProgress()) {
7977 SetGLError(GL_INVALID_OPERATION,
7978 "glCopyTexSubImage2D", "async upload pending for texture");
7979 return;
7980 }
7918 7981
7919 // Check we have compatible formats. 7982 // Check we have compatible formats.
7920 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7983 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7921 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7984 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7922 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); 7985 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7923 7986
7924 if (!channels_needed || 7987 if (!channels_needed ||
7925 (channels_needed & channels_exist) != channels_needed) { 7988 (channels_needed & channels_exist) != channels_needed) {
7926 SetGLError( 7989 SetGLError(
7927 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); 7990 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
8033 if (format != internal_format) { 8096 if (format != internal_format) {
8034 SetGLError(GL_INVALID_OPERATION, 8097 SetGLError(GL_INVALID_OPERATION,
8035 function_name, "format does not match internal format."); 8098 function_name, "format does not match internal format.");
8036 return false; 8099 return false;
8037 } 8100 }
8038 if (type != current_type) { 8101 if (type != current_type) {
8039 SetGLError(GL_INVALID_OPERATION, 8102 SetGLError(GL_INVALID_OPERATION,
8040 function_name, "type does not match type of texture."); 8103 function_name, "type does not match type of texture.");
8041 return false; 8104 return false;
8042 } 8105 }
8106 if (info->AsyncTransferIsInProgress()) {
8107 SetGLError(GL_INVALID_OPERATION,
8108 function_name, "async upload pending for texture");
8109 return false;
8110 }
8043 if (!info->ValidForTexture( 8111 if (!info->ValidForTexture(
8044 target, level, xoffset, yoffset, width, height, format, type)) { 8112 target, level, xoffset, yoffset, width, height, format, type)) {
8045 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions."); 8113 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions.");
8046 return false; 8114 return false;
8047 } 8115 }
8048 if ((GLES2Util::GetChannelsForFormat(format) & 8116 if ((GLES2Util::GetChannelsForFormat(format) &
8049 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8117 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8050 SetGLError( 8118 SetGLError(
8051 GL_INVALID_OPERATION, 8119 GL_INVALID_OPERATION,
8052 function_name, "can not supply data for depth or stencil textures"); 8120 function_name, "can not supply data for depth or stencil textures");
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after
9674 SetGLError(GL_INVALID_OPERATION, 9742 SetGLError(GL_INVALID_OPERATION,
9675 "glTraceEndCHROMIUM", "no trace begin found"); 9743 "glTraceEndCHROMIUM", "no trace begin found");
9676 return; 9744 return;
9677 } 9745 }
9678 9746
9679 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); 9747 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9680 trace->EnableEndTrace(); 9748 trace->EnableEndTrace();
9681 gpu_trace_stack_.pop(); 9749 gpu_trace_stack_.pop();
9682 } 9750 }
9683 9751
9752 bool GLES2DecoderImpl::ValidateAsyncTransfer(
9753 const char* function_name,
9754 TextureManager::TextureInfo* info,
9755 GLenum target,
9756 GLint level,
9757 const void * data) {
9758 // We only support async uploads to 2D textures for now.
9759 if (GL_TEXTURE_2D != target) {
9760 SetGLErrorInvalidEnum(function_name, target, "target");
9761 return false;
9762 }
9763 // We only support uploads to level zero for now.
9764 if (level != 0) {
9765 SetGLError(GL_INVALID_VALUE, function_name, "level != 0");
9766 return false;
9767 }
9768 // A transfer buffer must be bound, even for asyncTexImage2D.
9769 if (data == NULL) {
9770 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0");
9771 return false;
9772 }
9773 // We only support one async transfer in progress.
9774 if (!info || info->AsyncTransferIsInProgress()) {
9775 SetGLError(GL_INVALID_OPERATION,
9776 function_name, "transfer already in progress");
9777 return false;
9778 }
9779 return true;
9780 }
9781
9684 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( 9782 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
9685 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { 9783 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) {
9686 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); 9784 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
9687
9688 // TODO: This is a copy of HandleTexImage2D validation. Merge
9689 // as much of it as possible.
9690 tex_image_2d_failed_ = true;
9691 GLenum target = static_cast<GLenum>(c.target); 9785 GLenum target = static_cast<GLenum>(c.target);
9692 GLint level = static_cast<GLint>(c.level); 9786 GLint level = static_cast<GLint>(c.level);
9693 GLint internal_format = static_cast<GLint>(c.internalformat); 9787 GLint internal_format = static_cast<GLint>(c.internalformat);
9694 GLsizei width = static_cast<GLsizei>(c.width); 9788 GLsizei width = static_cast<GLsizei>(c.width);
9695 GLsizei height = static_cast<GLsizei>(c.height); 9789 GLsizei height = static_cast<GLsizei>(c.height);
9696 GLint border = static_cast<GLint>(c.border); 9790 GLint border = static_cast<GLint>(c.border);
9697 GLenum format = static_cast<GLenum>(c.format); 9791 GLenum format = static_cast<GLenum>(c.format);
9698 GLenum type = static_cast<GLenum>(c.type); 9792 GLenum type = static_cast<GLenum>(c.type);
9699 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 9793 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9700 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 9794 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9701 uint32 pixels_size; 9795 uint32 pixels_size;
9796
9797 // TODO(epenner): Move this and copies of this memory validation
9798 // into ValidateTexImage2D step.
9702 if (!GLES2Util::ComputeImageDataSizes( 9799 if (!GLES2Util::ComputeImageDataSizes(
9703 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 9800 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
9704 NULL)) { 9801 NULL)) {
9705 return error::kOutOfBounds; 9802 return error::kOutOfBounds;
9706 } 9803 }
9707 const void* pixels = NULL; 9804 const void* pixels = NULL;
9708 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 9805 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9709 pixels = GetSharedMemoryAs<const void*>( 9806 pixels = GetSharedMemoryAs<const void*>(
9710 pixels_shm_id, pixels_shm_offset, pixels_size); 9807 pixels_shm_id, pixels_shm_offset, pixels_size);
9711 if (!pixels) { 9808 if (!pixels) {
9712 return error::kOutOfBounds; 9809 return error::kOutOfBounds;
9713 } 9810 }
9714 } 9811 }
9715 9812
9716 // TODO(epenner): Do this via an async task. 9813 // All the normal glTexSubImage2D validation.
9717 DoTexImage2D( 9814 if (!ValidateTexImage2D(
9718 target, level, internal_format, width, height, border, format, type, 9815 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
9719 pixels, pixels_size); 9816 width, height, border, format, type, pixels, pixels_size)) {
9817 return error::kNoError;
9818 }
9819
9820 // Extra async validation.
9821 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9822 if (!ValidateAsyncTransfer(
9823 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels))
9824 return error::kNoError;
9825
9826 // Don't allow async redefinition of a textures.
9827 if (info->IsDefined()) {
9828 SetGLError(GL_INVALID_OPERATION,
9829 "glAsyncTexImage2DCHROMIUM", "already defined");
9830 return error::kNoError;
9831 }
9832
9833 // We know the memory/size is safe, so get the real shared memory since
9834 // it might need to be duped to prevent use-after-free of the memory.
9835 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
9836 base::SharedMemory* shared_memory = buffer.shared_memory;
9837 uint32 shm_size = buffer.size;
9838 uint32 shm_data_offset = c.pixels_shm_offset;
9839 uint32 shm_data_size = pixels_size;
9840
9841 // Set up the async state if needed, and make the texture
9842 // immutable so the async state stays valid. The level info
9843 // is set up lazily when the transfer completes.
9844 DCHECK(!info->GetAsyncTransferState());
9845 info->SetAsyncTransferState(
9846 async_pixel_transfer_delegate_->
9847 CreatePixelTransferState(info->service_id()));
9848 info->SetImmutable(true);
9849
9850 // Issue the async call and set up the texture.
9851 GLenum gl_internal_format =
9852 GetTexInternalFormat(internal_format, format, type);
9853 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
9854 width, height, border, format, type};
9855 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9856 shm_data_offset, shm_data_size};
9857
9858 // Add a pending transfer to the texture manager, which will bind the
9859 // transfer data to the texture and set the level info at the same time,
9860 // after the the transfer is complete.
9861 texture_manager()->AddPendingAsyncPixelTransfer(
9862 info->GetAsyncTransferState()->AsWeakPtr(), info);
9863
9864 async_pixel_transfer_delegate_->AsyncTexImage2D(
9865 info->GetAsyncTransferState(), tex_params, mem_params);
9720 return error::kNoError; 9866 return error::kNoError;
9721 } 9867 }
9722 9868
9723 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( 9869 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
9724 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { 9870 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) {
9725 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); 9871 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
9726
9727 // TODO: This is a copy of HandleTexSubImage2D validation. Merge
9728 // as much of it as possible.
9729 GLenum target = static_cast<GLenum>(c.target); 9872 GLenum target = static_cast<GLenum>(c.target);
9730 GLint level = static_cast<GLint>(c.level); 9873 GLint level = static_cast<GLint>(c.level);
9731 GLint xoffset = static_cast<GLint>(c.xoffset); 9874 GLint xoffset = static_cast<GLint>(c.xoffset);
9732 GLint yoffset = static_cast<GLint>(c.yoffset); 9875 GLint yoffset = static_cast<GLint>(c.yoffset);
9733 GLsizei width = static_cast<GLsizei>(c.width); 9876 GLsizei width = static_cast<GLsizei>(c.width);
9734 GLsizei height = static_cast<GLsizei>(c.height); 9877 GLsizei height = static_cast<GLsizei>(c.height);
9735 GLenum format = static_cast<GLenum>(c.format); 9878 GLenum format = static_cast<GLenum>(c.format);
9736 GLenum type = static_cast<GLenum>(c.type); 9879 GLenum type = static_cast<GLenum>(c.type);
9880
9881 // TODO(epenner): Move this and copies of this memory validation
9882 // into ValidateTexSubImage2D step.
9737 uint32 data_size; 9883 uint32 data_size;
9738 if (!GLES2Util::ComputeImageDataSizes( 9884 if (!GLES2Util::ComputeImageDataSizes(
9739 width, height, format, type, state_.unpack_alignment, &data_size, 9885 width, height, format, type, state_.unpack_alignment, &data_size,
9740 NULL, NULL)) { 9886 NULL, NULL)) {
9741 return error::kOutOfBounds; 9887 return error::kOutOfBounds;
9742 } 9888 }
9743 const void* pixels = GetSharedMemoryAs<const void*>( 9889 const void* pixels = GetSharedMemoryAs<const void*>(
9744 c.data_shm_id, c.data_shm_offset, data_size); 9890 c.data_shm_id, c.data_shm_offset, data_size);
9745 if (pixels == NULL) { 9891
9746 return error::kOutOfBounds; 9892 // All the normal glTexSubImage2D validation.
9893 error::Error error = error::kNoError;
9894 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
9895 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
9896 return error;
9747 } 9897 }
9748 9898
9749 // TODO(epenner): Do this via an async task. 9899 // Extra async validation.
9750 return DoTexSubImage2D( 9900 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9751 target, level, xoffset, yoffset, width, height, format, type, pixels); 9901 if (!ValidateAsyncTransfer(
9902 "glAsyncTexSubImage2DCHROMIUM", info, target, level, pixels))
9903 return error::kNoError;
9904
9905 // Guarantee async textures are always 'cleared' as follows:
9906 // - AsyncTexImage2D can not redefine an existing texture
9907 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
9908 // - AsyncTexSubImage2D clears synchronously if not already cleared.
9909 // - Textures become immutable after an async call.
9910 // This way we know in all cases that an async texture is always clear.
9911 if (!info->SafeToRenderFrom()) {
9912 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
9913 SetGLError(GL_OUT_OF_MEMORY,
9914 "glAsyncTexSubImage2DCHROMIUM","dimensions too big");
9915 return error::kNoError;
9916 }
9917 }
9918
9919 // We know the memory/size is safe, so get the real shared memory since
9920 // it might need to be duped to prevent use-after-free of the memory.
9921 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
9922 base::SharedMemory* shared_memory = buffer.shared_memory;
9923 uint32 shm_size = buffer.size;
9924 uint32 shm_data_offset = c.data_shm_offset;
9925 uint32 shm_data_size = data_size;
9926
9927 if (!info->GetAsyncTransferState()) {
9928 // Set up the async state if needed, and make the texture
9929 // immutable so the async state stays valid.
9930 info->SetAsyncTransferState(
9931 async_pixel_transfer_delegate_->
9932 CreatePixelTransferState(info->service_id()));
9933 info->SetImmutable(true);
9934 }
9935
9936 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
9937 width, height, format, type};
9938 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9939 shm_data_offset, shm_data_size};
9940 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
9941 info->GetAsyncTransferState(), tex_params, mem_params);
9942 return error::kNoError;
9752 } 9943 }
9753 9944
9754 // Include the auto-generated part of this file. We split this because it means 9945 // Include the auto-generated part of this file. We split this because it means
9755 // we can easily edit the non-auto generated parts right here in this file 9946 // we can easily edit the non-auto generated parts right here in this file
9756 // instead of having to edit some template or the code generator. 9947 // instead of having to edit some template or the code generator.
9757 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 9948 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9758 9949
9759 } // namespace gles2 9950 } // namespace gles2
9760 } // namespace gpu 9951 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698