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

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: Fix bots. 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 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698