OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 void DoTraceEndCHROMIUM(void); | 1070 void DoTraceEndCHROMIUM(void); |
1071 | 1071 |
1072 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs); | 1072 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs); |
1073 | 1073 |
1074 void DoLoseContextCHROMIUM(GLenum current, GLenum other); | 1074 void DoLoseContextCHROMIUM(GLenum current, GLenum other); |
1075 | 1075 |
1076 void DoFlushDriverCachesCHROMIUM(void); | 1076 void DoFlushDriverCachesCHROMIUM(void); |
1077 | 1077 |
1078 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix); | 1078 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix); |
1079 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); | 1079 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); |
| 1080 void DoScheduleCALayerFilterEffectsCHROMIUM( |
| 1081 GLsizei count, |
| 1082 const GLCALayerFilterEffect* filter_effects); |
1080 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, | 1083 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, |
1081 const GLuint* textures); | 1084 const GLuint* textures); |
1082 | 1085 |
1083 // Creates a Program for the given program. | 1086 // Creates a Program for the given program. |
1084 Program* CreateProgram(GLuint client_id, GLuint service_id) { | 1087 Program* CreateProgram(GLuint client_id, GLuint service_id) { |
1085 return program_manager()->CreateProgram(client_id, service_id); | 1088 return program_manager()->CreateProgram(client_id, service_id); |
1086 } | 1089 } |
1087 | 1090 |
1088 // Gets the program info for the given program. Returns NULL if none exists. | 1091 // Gets the program info for the given program. Returns NULL if none exists. |
1089 Program* GetProgram(GLuint client_id) { | 1092 Program* GetProgram(GLuint client_id) { |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 // populated, since they are needed to implement the workaround. | 2035 // populated, since they are needed to implement the workaround. |
2033 bool NeedsCopyTextureImageWorkaround(GLenum internal_format, | 2036 bool NeedsCopyTextureImageWorkaround(GLenum internal_format, |
2034 int32_t channels_exist, | 2037 int32_t channels_exist, |
2035 GLuint* source_texture_service_id, | 2038 GLuint* source_texture_service_id, |
2036 GLenum* source_texture_target); | 2039 GLenum* source_texture_target); |
2037 | 2040 |
2038 // Whether a texture backed by a Chromium Image needs to emulate GL_RGB format | 2041 // Whether a texture backed by a Chromium Image needs to emulate GL_RGB format |
2039 // using GL_RGBA and glColorMask. | 2042 // using GL_RGBA and glColorMask. |
2040 bool ChromiumImageNeedsRGBEmulation(); | 2043 bool ChromiumImageNeedsRGBEmulation(); |
2041 | 2044 |
| 2045 // The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and |
| 2046 // equivalent functions reset shared state. |
| 2047 void ClearScheduleCALayerState(); |
| 2048 |
2042 bool InitializeCopyTexImageBlitter(const char* function_name); | 2049 bool InitializeCopyTexImageBlitter(const char* function_name); |
2043 bool InitializeCopyTextureCHROMIUM(const char* function_name); | 2050 bool InitializeCopyTextureCHROMIUM(const char* function_name); |
2044 // Generate a member function prototype for each command in an automated and | 2051 // Generate a member function prototype for each command in an automated and |
2045 // typesafe way. | 2052 // typesafe way. |
2046 #define GLES2_CMD_OP(name) \ | 2053 #define GLES2_CMD_OP(name) \ |
2047 Error Handle##name(uint32_t immediate_data_size, const void* data); | 2054 Error Handle##name(uint32_t immediate_data_size, const void* data); |
2048 | 2055 |
2049 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 2056 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
2050 | 2057 |
2051 #undef GLES2_CMD_OP | 2058 #undef GLES2_CMD_OP |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2292 | 2299 |
2293 struct CALayerSharedState{ | 2300 struct CALayerSharedState{ |
2294 float opacity; | 2301 float opacity; |
2295 bool is_clipped; | 2302 bool is_clipped; |
2296 gfx::Rect clip_rect; | 2303 gfx::Rect clip_rect; |
2297 int sorting_context_id; | 2304 int sorting_context_id; |
2298 gfx::Transform transform; | 2305 gfx::Transform transform; |
2299 }; | 2306 }; |
2300 | 2307 |
2301 std::unique_ptr<CALayerSharedState> ca_layer_shared_state_; | 2308 std::unique_ptr<CALayerSharedState> ca_layer_shared_state_; |
| 2309 std::vector<ui::CARendererLayerParams::FilterEffect> ca_layer_filter_effects_; |
2302 | 2310 |
2303 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 2311 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
2304 }; | 2312 }; |
2305 | 2313 |
2306 const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = { | 2314 const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = { |
2307 #define GLES2_CMD_OP(name) \ | 2315 #define GLES2_CMD_OP(name) \ |
2308 { \ | 2316 { \ |
2309 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \ | 2317 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \ |
2310 cmds::name::cmd_flags, \ | 2318 cmds::name::cmd_flags, \ |
2311 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \ | 2319 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \ |
(...skipping 8443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10755 bool is_tracing; | 10763 bool is_tracing; |
10756 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), | 10764 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), |
10757 &is_tracing); | 10765 &is_tracing); |
10758 if (is_tracing) { | 10766 if (is_tracing) { |
10759 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); | 10767 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); |
10760 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); | 10768 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); |
10761 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( | 10769 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( |
10762 is_offscreen ? offscreen_size_ : surface_->GetSize()); | 10770 is_offscreen ? offscreen_size_ : surface_->GetSize()); |
10763 } | 10771 } |
10764 | 10772 |
10765 // The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and | 10773 ClearScheduleCALayerState(); |
10766 // equivalent functions reset shared state. | |
10767 ca_layer_shared_state_.reset(); | |
10768 | 10774 |
10769 if (supports_async_swap_) { | 10775 if (supports_async_swap_) { |
10770 TRACE_EVENT_ASYNC_BEGIN0("cc", "GLES2DecoderImpl::AsyncSwapBuffers", this); | 10776 TRACE_EVENT_ASYNC_BEGIN0("cc", "GLES2DecoderImpl::AsyncSwapBuffers", this); |
10771 surface_->PostSubBufferAsync( | 10777 surface_->PostSubBufferAsync( |
10772 c.x, c.y, c.width, c.height, | 10778 c.x, c.y, c.width, c.height, |
10773 base::Bind(&GLES2DecoderImpl::FinishSwapBuffers, | 10779 base::Bind(&GLES2DecoderImpl::FinishSwapBuffers, |
10774 base::AsWeakPtr(this))); | 10780 base::AsWeakPtr(this))); |
10775 } else { | 10781 } else { |
10776 FinishSwapBuffers(surface_->PostSubBuffer(c.x, c.y, c.width, c.height)); | 10782 FinishSwapBuffers(surface_->PostSubBuffer(c.x, c.y, c.width, c.height)); |
10777 } | 10783 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10885 } | 10891 } |
10886 | 10892 |
10887 const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, | 10893 const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, |
10888 8 * sizeof(GLfloat)); | 10894 8 * sizeof(GLfloat)); |
10889 if (!mem) { | 10895 if (!mem) { |
10890 return error::kOutOfBounds; | 10896 return error::kOutOfBounds; |
10891 } | 10897 } |
10892 gfx::RectF contents_rect(mem[0], mem[1], mem[2], mem[3]); | 10898 gfx::RectF contents_rect(mem[0], mem[1], mem[2], mem[3]); |
10893 gfx::RectF bounds_rect(mem[4], mem[5], mem[6], mem[7]); | 10899 gfx::RectF bounds_rect(mem[4], mem[5], mem[6], mem[7]); |
10894 | 10900 |
| 10901 // TODO(erikchen): Pass through filter effects. https://crbug.com/581526. |
| 10902 ca_layer_filter_effects_.clear(); |
10895 ui::CARendererLayerParams params = ui::CARendererLayerParams( | 10903 ui::CARendererLayerParams params = ui::CARendererLayerParams( |
10896 ca_layer_shared_state_->is_clipped, ca_layer_shared_state_->clip_rect, | 10904 ca_layer_shared_state_->is_clipped, ca_layer_shared_state_->clip_rect, |
10897 ca_layer_shared_state_->sorting_context_id, | 10905 ca_layer_shared_state_->sorting_context_id, |
10898 ca_layer_shared_state_->transform, image, contents_rect, | 10906 ca_layer_shared_state_->transform, image, contents_rect, |
10899 gfx::ToEnclosingRect(bounds_rect), c.background_color, c.edge_aa_mask, | 10907 gfx::ToEnclosingRect(bounds_rect), c.background_color, c.edge_aa_mask, |
10900 ca_layer_shared_state_->opacity, filter); | 10908 ca_layer_shared_state_->opacity, filter); |
10901 if (!surface_->ScheduleCALayer(params)) { | 10909 if (!surface_->ScheduleCALayer(params)) { |
10902 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM", | 10910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM", |
10903 "failed to schedule CALayer"); | 10911 "failed to schedule CALayer"); |
10904 } | 10912 } |
10905 return error::kNoError; | 10913 return error::kNoError; |
10906 } | 10914 } |
10907 | 10915 |
| 10916 void GLES2DecoderImpl::DoScheduleCALayerFilterEffectsCHROMIUM( |
| 10917 GLsizei count, |
| 10918 const GLCALayerFilterEffect* filter_effects) { |
| 10919 std::vector<ui::CARendererLayerParams::FilterEffect> effects; |
| 10920 effects.reserve(count); |
| 10921 for (GLsizei i = 0; i < count; ++i) { |
| 10922 const GLCALayerFilterEffect& filter_effect = filter_effects[i]; |
| 10923 GLint min = |
| 10924 static_cast<GLint>(ui::CARendererLayerParams::FilterEffectType::MIN); |
| 10925 GLint max = |
| 10926 static_cast<GLint>(ui::CARendererLayerParams::FilterEffectType::MAX); |
| 10927 if (filter_effect.type < min || filter_effect.type > max) { |
| 10928 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| 10929 "glScheduleCALayerFilterEffectsCHROMIUM", |
| 10930 "Invalid filter type."); |
| 10931 return; |
| 10932 } |
| 10933 ui::CARendererLayerParams::FilterEffectType filter_type = |
| 10934 static_cast<ui::CARendererLayerParams::FilterEffectType>( |
| 10935 filter_effect.type); |
| 10936 |
| 10937 ui::CARendererLayerParams::FilterEffect& effect = effects[i]; |
| 10938 effect.type = filter_type; |
| 10939 effect.amount = filter_effect.amount; |
| 10940 effect.drop_shadow_offset = gfx::Point(filter_effect.drop_shadow_offset_x, |
| 10941 filter_effect.drop_shadow_offset_y); |
| 10942 |
| 10943 static_assert(sizeof(GLuint) == sizeof(SkColor), |
| 10944 "GLuint and SkColor must have the same size."); |
| 10945 effect.drop_shadow_color = |
| 10946 static_cast<SkColor>(filter_effect.drop_shadow_color); |
| 10947 } |
| 10948 |
| 10949 ca_layer_filter_effects_.swap(effects); |
| 10950 } |
| 10951 |
10908 void GLES2DecoderImpl::DoScheduleCALayerInUseQueryCHROMIUM( | 10952 void GLES2DecoderImpl::DoScheduleCALayerInUseQueryCHROMIUM( |
10909 GLsizei count, | 10953 GLsizei count, |
10910 const GLuint* textures) { | 10954 const GLuint* textures) { |
10911 std::vector<gl::GLSurface::CALayerInUseQuery> queries; | 10955 std::vector<gl::GLSurface::CALayerInUseQuery> queries; |
10912 queries.reserve(count); | 10956 queries.reserve(count); |
10913 for (GLsizei i = 0; i < count; ++i) { | 10957 for (GLsizei i = 0; i < count; ++i) { |
10914 gl::GLImage* image = nullptr; | 10958 gl::GLImage* image = nullptr; |
10915 GLuint texture_id = textures[i]; | 10959 GLuint texture_id = textures[i]; |
10916 if (texture_id) { | 10960 if (texture_id) { |
10917 TextureRef* ref = texture_manager()->GetTexture(texture_id); | 10961 TextureRef* ref = texture_manager()->GetTexture(texture_id); |
(...skipping 2902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13820 | 13864 |
13821 bool is_tracing; | 13865 bool is_tracing; |
13822 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), | 13866 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), |
13823 &is_tracing); | 13867 &is_tracing); |
13824 if (is_tracing) { | 13868 if (is_tracing) { |
13825 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); | 13869 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); |
13826 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( | 13870 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( |
13827 is_offscreen ? offscreen_size_ : surface_->GetSize()); | 13871 is_offscreen ? offscreen_size_ : surface_->GetSize()); |
13828 } | 13872 } |
13829 | 13873 |
13830 // The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and | 13874 ClearScheduleCALayerState(); |
13831 // equivalent functions reset shared state. | |
13832 ca_layer_shared_state_.reset(); | |
13833 | 13875 |
13834 // If offscreen then don't actually SwapBuffers to the display. Just copy | 13876 // If offscreen then don't actually SwapBuffers to the display. Just copy |
13835 // the rendered frame to another frame buffer. | 13877 // the rendered frame to another frame buffer. |
13836 if (is_offscreen) { | 13878 if (is_offscreen) { |
13837 TRACE_EVENT2("gpu", "Offscreen", | 13879 TRACE_EVENT2("gpu", "Offscreen", |
13838 "width", offscreen_size_.width(), "height", offscreen_size_.height()); | 13880 "width", offscreen_size_.width(), "height", offscreen_size_.height()); |
13839 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { | 13881 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { |
13840 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, | 13882 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, |
13841 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will | 13883 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will |
13842 // fix this. | 13884 // fix this. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13942 } | 13984 } |
13943 } | 13985 } |
13944 | 13986 |
13945 void GLES2DecoderImpl::DoCommitOverlayPlanes() { | 13987 void GLES2DecoderImpl::DoCommitOverlayPlanes() { |
13946 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCommitOverlayPlanes"); | 13988 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCommitOverlayPlanes"); |
13947 if (!supports_commit_overlay_planes_) { | 13989 if (!supports_commit_overlay_planes_) { |
13948 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCommitOverlayPlanes", | 13990 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCommitOverlayPlanes", |
13949 "command not supported by surface"); | 13991 "command not supported by surface"); |
13950 return; | 13992 return; |
13951 } | 13993 } |
13952 // The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and | 13994 ClearScheduleCALayerState(); |
13953 // equivalent functions reset shared state. | |
13954 ca_layer_shared_state_.reset(); | |
13955 if (supports_async_swap_) { | 13995 if (supports_async_swap_) { |
13956 surface_->CommitOverlayPlanesAsync(base::Bind( | 13996 surface_->CommitOverlayPlanesAsync(base::Bind( |
13957 &GLES2DecoderImpl::FinishSwapBuffers, base::AsWeakPtr(this))); | 13997 &GLES2DecoderImpl::FinishSwapBuffers, base::AsWeakPtr(this))); |
13958 } else { | 13998 } else { |
13959 FinishSwapBuffers(surface_->CommitOverlayPlanes()); | 13999 FinishSwapBuffers(surface_->CommitOverlayPlanes()); |
13960 } | 14000 } |
13961 } | 14001 } |
13962 | 14002 |
13963 void GLES2DecoderImpl::DoSwapInterval(int interval) { | 14003 void GLES2DecoderImpl::DoSwapInterval(int interval) { |
13964 context_->SetSwapInterval(interval); | 14004 context_->SetSwapInterval(interval); |
(...skipping 3414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17379 *source_texture_target = texture->texture()->target(); | 17419 *source_texture_target = texture->texture()->target(); |
17380 *source_texture_service_id = texture->service_id(); | 17420 *source_texture_service_id = texture->service_id(); |
17381 return true; | 17421 return true; |
17382 } | 17422 } |
17383 | 17423 |
17384 bool GLES2DecoderImpl::ChromiumImageNeedsRGBEmulation() { | 17424 bool GLES2DecoderImpl::ChromiumImageNeedsRGBEmulation() { |
17385 gpu::ImageFactory* factory = GetContextGroup()->image_factory(); | 17425 gpu::ImageFactory* factory = GetContextGroup()->image_factory(); |
17386 return factory ? !factory->SupportsFormatRGB() : false; | 17426 return factory ? !factory->SupportsFormatRGB() : false; |
17387 } | 17427 } |
17388 | 17428 |
| 17429 void GLES2DecoderImpl::ClearScheduleCALayerState() { |
| 17430 ca_layer_shared_state_.reset(); |
| 17431 ca_layer_filter_effects_.clear(); |
| 17432 } |
| 17433 |
17389 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket( | 17434 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket( |
17390 uint32_t immediate_data_size, | 17435 uint32_t immediate_data_size, |
17391 const void* cmd_data) { | 17436 const void* cmd_data) { |
17392 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c = | 17437 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c = |
17393 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>( | 17438 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>( |
17394 cmd_data); | 17439 cmd_data); |
17395 if (!features().chromium_path_rendering) { | 17440 if (!features().chromium_path_rendering) { |
17396 return error::kUnknownCommand; | 17441 return error::kUnknownCommand; |
17397 } | 17442 } |
17398 | 17443 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17542 } | 17587 } |
17543 | 17588 |
17544 // Include the auto-generated part of this file. We split this because it means | 17589 // Include the auto-generated part of this file. We split this because it means |
17545 // we can easily edit the non-auto generated parts right here in this file | 17590 // we can easily edit the non-auto generated parts right here in this file |
17546 // instead of having to edit some template or the code generator. | 17591 // instead of having to edit some template or the code generator. |
17547 #include "base/macros.h" | 17592 #include "base/macros.h" |
17548 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17593 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
17549 | 17594 |
17550 } // namespace gles2 | 17595 } // namespace gles2 |
17551 } // namespace gpu | 17596 } // namespace gpu |
OLD | NEW |