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

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: Move BindFinishedTransfers to MakeCurrent. Rebase again. 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 4266 matching lines...) Expand 10 before | Expand all | Expand 10 after
7907 return; 7965 return;
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 }
greggman 2012/12/15 06:45:04 Don't you need to check here if (info->IsAsync
epenner 2012/12/17 06:29:18 Done.
7918 7976
7919 // Check we have compatible formats. 7977 // Check we have compatible formats.
7920 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7978 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7921 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7979 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7922 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); 7980 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7923 7981
7924 if (!channels_needed || 7982 if (!channels_needed ||
7925 (channels_needed & channels_exist) != channels_needed) { 7983 (channels_needed & channels_exist) != channels_needed) {
7926 SetGLError( 7984 SetGLError(
7927 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); 7985 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
8032 } 8090 }
8033 if (format != internal_format) { 8091 if (format != internal_format) {
8034 SetGLError(GL_INVALID_OPERATION, 8092 SetGLError(GL_INVALID_OPERATION,
8035 function_name, "format does not match internal format."); 8093 function_name, "format does not match internal format.");
8036 return false; 8094 return false;
8037 } 8095 }
8038 if (type != current_type) { 8096 if (type != current_type) {
8039 SetGLError(GL_INVALID_OPERATION, 8097 SetGLError(GL_INVALID_OPERATION,
8040 function_name, "type does not match type of texture."); 8098 function_name, "type does not match type of texture.");
8041 return false; 8099 return false;
8042 } 8100 }
greggman 2012/12/15 06:45:04 Don't you need to check that an async upload is no
epenner 2012/12/17 06:29:18 Done.
8043 if (!info->ValidForTexture( 8101 if (!info->ValidForTexture(
8044 target, level, xoffset, yoffset, width, height, format, type)) { 8102 target, level, xoffset, yoffset, width, height, format, type)) {
8045 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions."); 8103 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions.");
8046 return false; 8104 return false;
8047 } 8105 }
8048 if ((GLES2Util::GetChannelsForFormat(format) & 8106 if ((GLES2Util::GetChannelsForFormat(format) &
8049 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8107 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8050 SetGLError( 8108 SetGLError(
8051 GL_INVALID_OPERATION, 8109 GL_INVALID_OPERATION,
8052 function_name, "can not supply data for depth or stencil textures"); 8110 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, 9732 SetGLError(GL_INVALID_OPERATION,
9675 "glTraceEndCHROMIUM", "no trace begin found"); 9733 "glTraceEndCHROMIUM", "no trace begin found");
9676 return; 9734 return;
9677 } 9735 }
9678 9736
9679 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top(); 9737 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9680 trace->EnableEndTrace(); 9738 trace->EnableEndTrace();
9681 gpu_trace_stack_.pop(); 9739 gpu_trace_stack_.pop();
9682 } 9740 }
9683 9741
9742 bool GLES2DecoderImpl::ValidateAsyncTransfer(
9743 const char* function_name,
9744 TextureManager::TextureInfo* info,
9745 GLenum target,
9746 GLint level,
9747 const void * data) {
9748 // We only support async uploads to 2D textures for now.
9749 if (GL_TEXTURE_2D != target) {
9750 SetGLErrorInvalidEnum(function_name, target, "target");
9751 return false;
9752 }
9753 // We only support uploads to level zero for now.
9754 if (level != 0) {
9755 SetGLError(GL_INVALID_VALUE, function_name, "level != 0");
9756 return false;
9757 }
9758 // A transfer buffer must be bound, even for asyncTexImage2D.
9759 if (data == NULL) {
9760 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0");
9761 return false;
9762 }
9763 // We only support one async transfer in progress.
9764 if (!info || info->AsyncTransferIsInProgress()) {
9765 SetGLError(GL_INVALID_OPERATION,
9766 function_name, "transfer already in progress");
9767 return false;
9768 }
9769 return true;
9770 }
9771
9684 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( 9772 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
9685 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { 9773 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) {
9686 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); 9774 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); 9775 GLenum target = static_cast<GLenum>(c.target);
9692 GLint level = static_cast<GLint>(c.level); 9776 GLint level = static_cast<GLint>(c.level);
9693 GLint internal_format = static_cast<GLint>(c.internalformat); 9777 GLint internal_format = static_cast<GLint>(c.internalformat);
9694 GLsizei width = static_cast<GLsizei>(c.width); 9778 GLsizei width = static_cast<GLsizei>(c.width);
9695 GLsizei height = static_cast<GLsizei>(c.height); 9779 GLsizei height = static_cast<GLsizei>(c.height);
9696 GLint border = static_cast<GLint>(c.border); 9780 GLint border = static_cast<GLint>(c.border);
9697 GLenum format = static_cast<GLenum>(c.format); 9781 GLenum format = static_cast<GLenum>(c.format);
9698 GLenum type = static_cast<GLenum>(c.type); 9782 GLenum type = static_cast<GLenum>(c.type);
9699 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 9783 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9700 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 9784 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9701 uint32 pixels_size; 9785 uint32 pixels_size;
9786
9787 // TODO(epenner): Move this and copies of this memory validation
9788 // into ValidateTexImage2D step.
9702 if (!GLES2Util::ComputeImageDataSizes( 9789 if (!GLES2Util::ComputeImageDataSizes(
9703 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 9790 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
9704 NULL)) { 9791 NULL)) {
9705 return error::kOutOfBounds; 9792 return error::kOutOfBounds;
9706 } 9793 }
9707 const void* pixels = NULL; 9794 const void* pixels = NULL;
9708 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 9795 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9709 pixels = GetSharedMemoryAs<const void*>( 9796 pixels = GetSharedMemoryAs<const void*>(
9710 pixels_shm_id, pixels_shm_offset, pixels_size); 9797 pixels_shm_id, pixels_shm_offset, pixels_size);
9711 if (!pixels) { 9798 if (!pixels) {
9712 return error::kOutOfBounds; 9799 return error::kOutOfBounds;
9713 } 9800 }
9714 } 9801 }
9715 9802
9716 // TODO(epenner): Do this via an async task. 9803 // All the normal glTexSubImage2D validation.
9717 DoTexImage2D( 9804 if (!ValidateTexImage2D(
9718 target, level, internal_format, width, height, border, format, type, 9805 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
9719 pixels, pixels_size); 9806 width, height, border, format, type, pixels, pixels_size)) {
9807 return error::kNoError;
9808 }
9809
9810 // Extra async validation.
9811 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9812 if (!ValidateAsyncTransfer(
9813 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels))
9814 return error::kNoError;
9815
9816 // Don't allow async redefinition of a textures.
9817 if (info->IsDefined()) {
9818 SetGLError(GL_INVALID_OPERATION,
9819 "glAsyncTexImage2DCHROMIUM", "already defined");
9820 return error::kNoError;
9821 }
9822
9823 // We know the memory/size is safe, so get the real shared memory since
9824 // it might need to be duped to prevent use-after-free of the memory.
9825 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
9826 base::SharedMemory* shared_memory = buffer.shared_memory;
9827 uint32 shm_size = buffer.size;
9828 uint32 shm_data_offset = c.pixels_shm_offset;
9829 uint32 shm_data_size = pixels_size;
9830
9831 // Set up the async state if needed, and make the texture
9832 // immutable so the async state stays valid. The level info
9833 // is set up lazily when the transfer completes.
9834 DCHECK(!info->GetAsyncTransferState());
9835 info->SetAsyncTransferState(
9836 async_pixel_transfer_delegate_->
9837 CreatePixelTransferState(info->service_id()));
9838 info->SetImmutable(true);
9839
9840 // Issue the async call and set up the texture.
9841 GLenum gl_internal_format =
9842 GetTexInternalFormat(internal_format, format, type);
9843 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
9844 width, height, border, format, type};
9845 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9846 shm_data_offset, shm_data_size};
9847
9848 // Add a pending transfer to the texture manager, which will bind the
9849 // transfer data to the texture and set the level info at the same time,
9850 // after the the transfer is complete.
9851 texture_manager()->AddPendingAsyncPixelTransfer(
9852 info->GetAsyncTransferState()->AsWeakPtr(), info);
9853
9854 async_pixel_transfer_delegate_->AsyncTexImage2D(
9855 info->GetAsyncTransferState(), tex_params, mem_params);
9720 return error::kNoError; 9856 return error::kNoError;
9721 } 9857 }
9722 9858
9723 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( 9859 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
9724 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { 9860 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) {
9725 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); 9861 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); 9862 GLenum target = static_cast<GLenum>(c.target);
9730 GLint level = static_cast<GLint>(c.level); 9863 GLint level = static_cast<GLint>(c.level);
9731 GLint xoffset = static_cast<GLint>(c.xoffset); 9864 GLint xoffset = static_cast<GLint>(c.xoffset);
9732 GLint yoffset = static_cast<GLint>(c.yoffset); 9865 GLint yoffset = static_cast<GLint>(c.yoffset);
9733 GLsizei width = static_cast<GLsizei>(c.width); 9866 GLsizei width = static_cast<GLsizei>(c.width);
9734 GLsizei height = static_cast<GLsizei>(c.height); 9867 GLsizei height = static_cast<GLsizei>(c.height);
9735 GLenum format = static_cast<GLenum>(c.format); 9868 GLenum format = static_cast<GLenum>(c.format);
9736 GLenum type = static_cast<GLenum>(c.type); 9869 GLenum type = static_cast<GLenum>(c.type);
9870
9871 // TODO(epenner): Move this and copies of this memory validation
9872 // into ValidateTexSubImage2D step.
9737 uint32 data_size; 9873 uint32 data_size;
9738 if (!GLES2Util::ComputeImageDataSizes( 9874 if (!GLES2Util::ComputeImageDataSizes(
9739 width, height, format, type, state_.unpack_alignment, &data_size, 9875 width, height, format, type, state_.unpack_alignment, &data_size,
9740 NULL, NULL)) { 9876 NULL, NULL)) {
9741 return error::kOutOfBounds; 9877 return error::kOutOfBounds;
9742 } 9878 }
9743 const void* pixels = GetSharedMemoryAs<const void*>( 9879 const void* pixels = GetSharedMemoryAs<const void*>(
9744 c.data_shm_id, c.data_shm_offset, data_size); 9880 c.data_shm_id, c.data_shm_offset, data_size);
9745 if (pixels == NULL) { 9881
9746 return error::kOutOfBounds; 9882 // All the normal glTexSubImage2D validation.
9883 error::Error error = error::kNoError;
9884 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
9885 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
9886 return error;
9747 } 9887 }
9748 9888
9749 // TODO(epenner): Do this via an async task. 9889 // Extra async validation.
9750 return DoTexSubImage2D( 9890 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9751 target, level, xoffset, yoffset, width, height, format, type, pixels); 9891 if (!ValidateAsyncTransfer(
9892 "glAsyncTexSubImage2DCHROMIUM", info, target, level, pixels))
9893 return error::kNoError;
9894
9895 // Guarantee async textures are always 'cleared' as follows:
9896 // - AsyncTexImage2D can not redefine an existing texture
9897 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
9898 // - AsyncTexSubImage2D clears synchronously if not already cleared.
9899 // - Textures become immutable after an async call.
9900 // This way we know in all cases that an async texture is always clear.
9901 if (!info->SafeToRenderFrom()) {
9902 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
9903 SetGLError(GL_OUT_OF_MEMORY,
9904 "glAsyncTexSubImage2DCHROMIUM","dimensions too big");
9905 return error::kNoError;
9906 }
9907 }
9908
9909 // We know the memory/size is safe, so get the real shared memory since
9910 // it might need to be duped to prevent use-after-free of the memory.
9911 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
9912 base::SharedMemory* shared_memory = buffer.shared_memory;
9913 uint32 shm_size = buffer.size;
9914 uint32 shm_data_offset = c.data_shm_offset;
9915 uint32 shm_data_size = data_size;
9916
9917 if (!info->GetAsyncTransferState()) {
9918 // Set up the async state if needed, and make the texture
9919 // immutable so the async state stays valid.
9920 info->SetAsyncTransferState(
9921 async_pixel_transfer_delegate_->
9922 CreatePixelTransferState(info->service_id()));
9923 info->SetImmutable(true);
9924 }
9925
9926 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
9927 width, height, format, type};
9928 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9929 shm_data_offset, shm_data_size};
9930 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
9931 info->GetAsyncTransferState(), tex_params, mem_params);
9932 return error::kNoError;
9752 } 9933 }
9753 9934
9754 // Include the auto-generated part of this file. We split this because it means 9935 // 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 9936 // 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. 9937 // instead of having to edit some template or the code generator.
9757 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 9938 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9758 9939
9759 } // namespace gles2 9940 } // namespace gles2
9760 } // namespace gpu 9941 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698