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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 #include "gpu/command_buffer/service/program_manager.h" | 58 #include "gpu/command_buffer/service/program_manager.h" |
59 #include "gpu/command_buffer/service/query_manager.h" | 59 #include "gpu/command_buffer/service/query_manager.h" |
60 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 60 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
61 #include "gpu/command_buffer/service/sampler_manager.h" | 61 #include "gpu/command_buffer/service/sampler_manager.h" |
62 #include "gpu/command_buffer/service/shader_manager.h" | 62 #include "gpu/command_buffer/service/shader_manager.h" |
63 #include "gpu/command_buffer/service/shader_translator.h" | 63 #include "gpu/command_buffer/service/shader_translator.h" |
64 #include "gpu/command_buffer/service/texture_manager.h" | 64 #include "gpu/command_buffer/service/texture_manager.h" |
65 #include "gpu/command_buffer/service/transform_feedback_manager.h" | 65 #include "gpu/command_buffer/service/transform_feedback_manager.h" |
66 #include "gpu/command_buffer/service/vertex_array_manager.h" | 66 #include "gpu/command_buffer/service/vertex_array_manager.h" |
67 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 67 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
68 #if defined(OS_ANDROID) | |
69 #include "gpu/ipc/common/gpu_surface_lookup.h" | |
70 #endif | |
68 #include "third_party/angle/src/image_util/loadimage.h" | 71 #include "third_party/angle/src/image_util/loadimage.h" |
69 #include "third_party/smhasher/src/City.h" | 72 #include "third_party/smhasher/src/City.h" |
70 #include "ui/gfx/buffer_types.h" | 73 #include "ui/gfx/buffer_types.h" |
71 #include "ui/gfx/geometry/point.h" | 74 #include "ui/gfx/geometry/point.h" |
72 #include "ui/gfx/geometry/rect.h" | 75 #include "ui/gfx/geometry/rect.h" |
73 #include "ui/gfx/geometry/rect_conversions.h" | 76 #include "ui/gfx/geometry/rect_conversions.h" |
74 #include "ui/gfx/geometry/size.h" | 77 #include "ui/gfx/geometry/size.h" |
75 #include "ui/gfx/gpu_memory_buffer.h" | 78 #include "ui/gfx/gpu_memory_buffer.h" |
76 #include "ui/gfx/overlay_transform.h" | 79 #include "ui/gfx/overlay_transform.h" |
77 #include "ui/gfx/transform.h" | 80 #include "ui/gfx/transform.h" |
78 #include "ui/gl/ca_renderer_layer_params.h" | 81 #include "ui/gl/ca_renderer_layer_params.h" |
79 #include "ui/gl/gl_bindings.h" | 82 #include "ui/gl/gl_bindings.h" |
80 #include "ui/gl/gl_context.h" | 83 #include "ui/gl/gl_context.h" |
81 #include "ui/gl/gl_fence.h" | 84 #include "ui/gl/gl_fence.h" |
82 #include "ui/gl/gl_image.h" | 85 #include "ui/gl/gl_image.h" |
83 #include "ui/gl/gl_implementation.h" | 86 #include "ui/gl/gl_implementation.h" |
84 #include "ui/gl/gl_surface.h" | 87 #include "ui/gl/gl_surface.h" |
88 #if defined(OS_ANDROID) | |
89 #include "ui/gl/gl_surface_egl.h" | |
90 #endif | |
85 #include "ui/gl/gl_version_info.h" | 91 #include "ui/gl/gl_version_info.h" |
86 #include "ui/gl/gpu_timing.h" | 92 #include "ui/gl/gpu_timing.h" |
87 | 93 |
88 #if defined(OS_MACOSX) | 94 #if defined(OS_MACOSX) |
89 #include <IOSurface/IOSurface.h> | 95 #include <IOSurface/IOSurface.h> |
90 // Note that this must be included after gl_bindings.h to avoid conflicts. | 96 // Note that this must be included after gl_bindings.h to avoid conflicts. |
91 #include <OpenGL/CGLIOSurface.h> | 97 #include <OpenGL/CGLIOSurface.h> |
92 #endif | 98 #endif |
93 | 99 |
94 namespace gpu { | 100 namespace gpu { |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 | 1033 |
1028 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, | 1034 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, |
1029 const volatile GLfloat* matrix); | 1035 const volatile GLfloat* matrix); |
1030 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); | 1036 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); |
1031 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, | 1037 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, |
1032 const volatile GLuint* textures); | 1038 const volatile GLuint* textures); |
1033 | 1039 |
1034 void DoFlushMappedBufferRange( | 1040 void DoFlushMappedBufferRange( |
1035 GLenum target, GLintptr offset, GLsizeiptr size); | 1041 GLenum target, GLintptr offset, GLsizeiptr size); |
1036 | 1042 |
1043 void DoSetSurfaceHandleCHROMIUM(GLint surface_handle); | |
1044 | |
1045 // Apply creation attibutes such as depth_bits for the offscreen | |
1046 // framebuffer or active surface as applicable. | |
1047 GLint ApplySurfaceAttributesAndGetAlphaBits( | |
1048 bool offscreen, const ContextCreationAttribHelper& attrib_helper); | |
1049 | |
1050 // Apply feature flags and surface-specific workarounds to match the | |
1051 // capabilities of the current surface. Used by Initialize() and | |
1052 // DoSetSurfaceHandleCHROMIUM. | |
1053 void ApplySurfaceFeatures(); | |
1054 | |
1037 // Creates a Program for the given program. | 1055 // Creates a Program for the given program. |
1038 Program* CreateProgram(GLuint client_id, GLuint service_id) { | 1056 Program* CreateProgram(GLuint client_id, GLuint service_id) { |
1039 return program_manager()->CreateProgram(client_id, service_id); | 1057 return program_manager()->CreateProgram(client_id, service_id); |
1040 } | 1058 } |
1041 | 1059 |
1042 // Gets the program info for the given program. Returns NULL if none exists. | 1060 // Gets the program info for the given program. Returns NULL if none exists. |
1043 Program* GetProgram(GLuint client_id) { | 1061 Program* GetProgram(GLuint client_id) { |
1044 return program_manager()->GetProgram(client_id); | 1062 return program_manager()->GetProgram(client_id); |
1045 } | 1063 } |
1046 | 1064 |
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2124 Error Handle##name(uint32_t immediate_data_size, const volatile void* data); | 2142 Error Handle##name(uint32_t immediate_data_size, const volatile void* data); |
2125 | 2143 |
2126 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 2144 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
2127 | 2145 |
2128 #undef GLES2_CMD_OP | 2146 #undef GLES2_CMD_OP |
2129 | 2147 |
2130 // The GL context this decoder renders to on behalf of the client. | 2148 // The GL context this decoder renders to on behalf of the client. |
2131 scoped_refptr<gl::GLSurface> surface_; | 2149 scoped_refptr<gl::GLSurface> surface_; |
2132 scoped_refptr<gl::GLContext> context_; | 2150 scoped_refptr<gl::GLContext> context_; |
2133 | 2151 |
2152 ContextCreationAttribHelper attrib_helper_; | |
2153 | |
2154 // Direct render mode data for switching and restoring the | |
2155 // underlying destination surface, cf. DoSetSurfaceHandleCHROMIUM. | |
2156 struct DirectRenderState{ | |
2157 scoped_refptr<gl::GLSurface> direct_surface; | |
2158 scoped_refptr<gl::GLSurface> orig_surface; | |
2159 std::unique_ptr<BackFramebuffer> orig_offscreen_target_frame_buffer; | |
2160 }; | |
2161 std::unique_ptr<DirectRenderState> direct_render_state_; | |
2162 | |
2134 // The ContextGroup for this decoder uses to track resources. | 2163 // The ContextGroup for this decoder uses to track resources. |
2135 scoped_refptr<ContextGroup> group_; | 2164 scoped_refptr<ContextGroup> group_; |
2136 | 2165 |
2137 DebugMarkerManager debug_marker_manager_; | 2166 DebugMarkerManager debug_marker_manager_; |
2138 Logger logger_; | 2167 Logger logger_; |
2139 | 2168 |
2140 // All the state for this context. | 2169 // All the state for this context. |
2141 ContextState state_; | 2170 ContextState state_; |
2142 | 2171 |
2143 std::unique_ptr<TransformFeedbackManager> transform_feedback_manager_; | 2172 std::unique_ptr<TransformFeedbackManager> transform_feedback_manager_; |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2990 validation_fbo_multisample_(0), | 3019 validation_fbo_multisample_(0), |
2991 validation_fbo_(0), | 3020 validation_fbo_(0), |
2992 texture_manager_service_id_generation_(0), | 3021 texture_manager_service_id_generation_(0), |
2993 force_shader_name_hashing_for_test(false) { | 3022 force_shader_name_hashing_for_test(false) { |
2994 DCHECK(group); | 3023 DCHECK(group); |
2995 } | 3024 } |
2996 | 3025 |
2997 GLES2DecoderImpl::~GLES2DecoderImpl() { | 3026 GLES2DecoderImpl::~GLES2DecoderImpl() { |
2998 } | 3027 } |
2999 | 3028 |
3029 GLint GLES2DecoderImpl::ApplySurfaceAttributesAndGetAlphaBits( | |
3030 bool offscreen, const ContextCreationAttribHelper& attrib_helper) { | |
3031 GLint alpha_bits = 0; | |
3032 | |
3033 if (offscreen) { | |
3034 offscreen_buffer_should_have_alpha_ = attrib_helper.alpha_size > 0; | |
3035 | |
3036 // Whether the offscreen buffer texture should have an alpha channel. Does | |
3037 // not include logic from workarounds. | |
3038 bool offscreen_buffer_texture_needs_alpha = | |
3039 offscreen_buffer_should_have_alpha_ || | |
3040 (ChromiumImageNeedsRGBEmulation() && | |
3041 attrib_helper.should_use_native_gmb_for_backbuffer); | |
3042 | |
3043 if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 && | |
3044 features().chromium_framebuffer_multisample) { | |
3045 // Per ext_framebuffer_multisample spec, need max bound on sample count. | |
3046 // max_sample_count must be initialized to a sane value. If | |
3047 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. | |
3048 GLint max_sample_count = 1; | |
3049 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); | |
3050 offscreen_target_samples_ = std::min(attrib_helper.samples, | |
3051 max_sample_count); | |
3052 } else { | |
3053 offscreen_target_samples_ = 1; | |
3054 } | |
3055 offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved; | |
3056 | |
3057 if (gl_version_info().is_es) { | |
3058 const bool rgb8_supported = context_->HasExtension("GL_OES_rgb8_rgba8"); | |
3059 // The only available default render buffer formats in GLES2 have very | |
3060 // little precision. Don't enable multisampling unless 8-bit render | |
3061 // buffer formats are available--instead fall back to 8-bit textures. | |
3062 if (rgb8_supported && offscreen_target_samples_ > 1) { | |
3063 offscreen_target_color_format_ = | |
3064 offscreen_buffer_texture_needs_alpha ? GL_RGBA8 : GL_RGB8; | |
3065 } else { | |
3066 offscreen_target_samples_ = 1; | |
3067 offscreen_target_color_format_ = | |
3068 offscreen_buffer_texture_needs_alpha || | |
3069 workarounds().disable_gl_rgb_format | |
3070 ? GL_RGBA | |
3071 : GL_RGB; | |
3072 } | |
3073 | |
3074 // ANGLE only supports packed depth/stencil formats, so use it if it is | |
3075 // available. | |
3076 const bool depth24_stencil8_supported = | |
3077 feature_info_->feature_flags().packed_depth24_stencil8; | |
3078 VLOG(1) << "GL_OES_packed_depth_stencil " | |
3079 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3080 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3081 depth24_stencil8_supported) { | |
3082 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3083 offscreen_target_stencil_format_ = 0; | |
3084 } else { | |
3085 // It may be the case that this depth/stencil combination is not | |
3086 // supported, but this will be checked later by CheckFramebufferStatus. | |
3087 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3088 GL_DEPTH_COMPONENT16 : 0; | |
3089 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3090 GL_STENCIL_INDEX8 : 0; | |
3091 } | |
3092 } else { | |
3093 offscreen_target_color_format_ = | |
3094 offscreen_buffer_texture_needs_alpha || | |
3095 workarounds().disable_gl_rgb_format | |
3096 ? GL_RGBA | |
3097 : GL_RGB; | |
3098 | |
3099 // If depth is requested at all, use the packed depth stencil format if | |
3100 // it's available, as some desktop GL drivers don't support any non-packed | |
3101 // formats for depth attachments. | |
3102 const bool depth24_stencil8_supported = | |
3103 feature_info_->feature_flags().packed_depth24_stencil8; | |
3104 VLOG(1) << "GL_EXT_packed_depth_stencil " | |
3105 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3106 | |
3107 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3108 depth24_stencil8_supported) { | |
3109 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3110 offscreen_target_stencil_format_ = 0; | |
3111 } else { | |
3112 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3113 GL_DEPTH_COMPONENT : 0; | |
3114 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3115 GL_STENCIL_INDEX : 0; | |
3116 } | |
3117 } | |
3118 | |
3119 offscreen_saved_color_format_ = offscreen_buffer_texture_needs_alpha || | |
3120 workarounds().disable_gl_rgb_format | |
3121 ? GL_RGBA | |
3122 : GL_RGB; | |
3123 } else { | |
3124 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); | |
3125 // These are NOT if the back buffer has these proprorties. They are | |
3126 // if we want the command buffer to enforce them regardless of what | |
3127 // the real backbuffer is assuming the real back buffer gives us more than | |
3128 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll | |
3129 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we | |
3130 // can't do anything about that. | |
3131 | |
3132 if (!surfaceless_) { | |
3133 GLint depth_bits = 0; | |
3134 GLint stencil_bits = 0; | |
3135 | |
3136 bool default_fb = (GetBackbufferServiceId() == 0); | |
3137 | |
3138 if (gl_version_info().is_desktop_core_profile) { | |
3139 glGetFramebufferAttachmentParameterivEXT( | |
3140 GL_FRAMEBUFFER, | |
3141 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, | |
3142 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); | |
3143 glGetFramebufferAttachmentParameterivEXT( | |
3144 GL_FRAMEBUFFER, | |
3145 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, | |
3146 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); | |
3147 glGetFramebufferAttachmentParameterivEXT( | |
3148 GL_FRAMEBUFFER, | |
3149 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, | |
3150 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); | |
3151 } else { | |
3152 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); | |
3153 glGetIntegerv(GL_DEPTH_BITS, &depth_bits); | |
3154 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); | |
3155 } | |
3156 | |
3157 // This checks if the user requested RGBA and we have RGBA then RGBA. If | |
3158 // the user requested RGB then RGB. If the user did not specify a | |
3159 // preference than use whatever we were given. Same for DEPTH and STENCIL. | |
3160 back_buffer_color_format_ = | |
3161 (attrib_helper.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; | |
3162 back_buffer_has_depth_ = attrib_helper.depth_size != 0 && depth_bits > 0; | |
3163 back_buffer_has_stencil_ = | |
3164 attrib_helper.stencil_size != 0 && stencil_bits > 0; | |
3165 } | |
3166 } | |
3167 | |
3168 return alpha_bits; | |
3169 } | |
3170 | |
3171 void GLES2DecoderImpl::ApplySurfaceFeatures() { | |
3172 supports_post_sub_buffer_ = surface_->SupportsPostSubBuffer(); | |
3173 if (workarounds() | |
3174 .disable_post_sub_buffers_for_onscreen_surfaces && | |
3175 !surface_->IsOffscreen()) | |
3176 supports_post_sub_buffer_ = false; | |
3177 | |
3178 supports_swap_buffers_with_damage_ = | |
3179 surface_->SupportsSwapBuffersWithDamage(); | |
3180 | |
3181 supports_commit_overlay_planes_ = surface_->SupportsCommitOverlayPlanes(); | |
3182 | |
3183 supports_async_swap_ = surface_->SupportsAsyncSwap(); | |
3184 } | |
3185 | |
3000 bool GLES2DecoderImpl::Initialize( | 3186 bool GLES2DecoderImpl::Initialize( |
3001 const scoped_refptr<gl::GLSurface>& surface, | 3187 const scoped_refptr<gl::GLSurface>& surface, |
3002 const scoped_refptr<gl::GLContext>& context, | 3188 const scoped_refptr<gl::GLContext>& context, |
3003 bool offscreen, | 3189 bool offscreen, |
3004 const DisallowedFeatures& disallowed_features, | 3190 const DisallowedFeatures& disallowed_features, |
3005 const ContextCreationAttribHelper& attrib_helper) { | 3191 const ContextCreationAttribHelper& attrib_helper) { |
3006 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); | 3192 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); |
3007 DCHECK(context->IsCurrent(surface.get())); | 3193 DCHECK(context->IsCurrent(surface.get())); |
3008 DCHECK(!context_.get()); | 3194 DCHECK(!context_.get()); |
3009 | 3195 |
3196 // Save the attrib helper data for future use in ApplySurfaceFeatures. | |
3197 attrib_helper_ = attrib_helper; | |
3198 | |
3010 surfaceless_ = surface->IsSurfaceless() && !offscreen; | 3199 surfaceless_ = surface->IsSurfaceless() && !offscreen; |
3011 | 3200 |
3012 set_initialized(); | 3201 set_initialized(); |
3013 gpu_state_tracer_ = GPUStateTracer::Create(&state_); | 3202 gpu_state_tracer_ = GPUStateTracer::Create(&state_); |
3014 | 3203 |
3015 if (group_->gpu_preferences().enable_gpu_debugging) | 3204 if (group_->gpu_preferences().enable_gpu_debugging) |
3016 set_debug(true); | 3205 set_debug(true); |
3017 | 3206 |
3018 if (group_->gpu_preferences().enable_gpu_command_logging) | 3207 if (group_->gpu_preferences().enable_gpu_command_logging) |
3019 set_log_commands(true); | 3208 set_log_commands(true); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3172 state_.texture_units[tt].bound_texture_cube_map = ref; | 3361 state_.texture_units[tt].bound_texture_cube_map = ref; |
3173 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); | 3362 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); |
3174 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); | 3363 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); |
3175 state_.texture_units[tt].bound_texture_2d = ref; | 3364 state_.texture_units[tt].bound_texture_2d = ref; |
3176 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); | 3365 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); |
3177 } | 3366 } |
3178 glActiveTexture(GL_TEXTURE0); | 3367 glActiveTexture(GL_TEXTURE0); |
3179 CHECK_GL_ERROR(); | 3368 CHECK_GL_ERROR(); |
3180 | 3369 |
3181 // cache ALPHA_BITS result for re-use with clear behaviour | 3370 // cache ALPHA_BITS result for re-use with clear behaviour |
3182 GLint alpha_bits = 0; | 3371 GLint alpha_bits = ApplySurfaceAttributesAndGetAlphaBits( |
3372 offscreen, attrib_helper); | |
3183 | 3373 |
3184 if (offscreen) { | 3374 if (offscreen) { |
3185 offscreen_buffer_should_have_alpha_ = attrib_helper.alpha_size > 0; | 3375 gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size; |
3186 | 3376 |
3187 // Whether the offscreen buffer texture should have an alpha channel. Does | |
3188 // not include logic from workarounds. | |
3189 bool offscreen_buffer_texture_needs_alpha = | |
3190 offscreen_buffer_should_have_alpha_ || | |
3191 (ChromiumImageNeedsRGBEmulation() && | |
3192 attrib_helper.should_use_native_gmb_for_backbuffer); | |
3193 | |
3194 if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 && | |
3195 features().chromium_framebuffer_multisample) { | |
3196 // Per ext_framebuffer_multisample spec, need max bound on sample count. | |
3197 // max_sample_count must be initialized to a sane value. If | |
3198 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. | |
3199 GLint max_sample_count = 1; | |
3200 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); | |
3201 offscreen_target_samples_ = std::min(attrib_helper.samples, | |
3202 max_sample_count); | |
3203 } else { | |
3204 offscreen_target_samples_ = 1; | |
3205 } | |
3206 offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved; | |
3207 | |
3208 if (gl_version_info().is_es) { | |
3209 const bool rgb8_supported = context_->HasExtension("GL_OES_rgb8_rgba8"); | |
3210 // The only available default render buffer formats in GLES2 have very | |
3211 // little precision. Don't enable multisampling unless 8-bit render | |
3212 // buffer formats are available--instead fall back to 8-bit textures. | |
3213 if (rgb8_supported && offscreen_target_samples_ > 1) { | |
3214 offscreen_target_color_format_ = | |
3215 offscreen_buffer_texture_needs_alpha ? GL_RGBA8 : GL_RGB8; | |
3216 } else { | |
3217 offscreen_target_samples_ = 1; | |
3218 offscreen_target_color_format_ = | |
3219 offscreen_buffer_texture_needs_alpha || | |
3220 workarounds().disable_gl_rgb_format | |
3221 ? GL_RGBA | |
3222 : GL_RGB; | |
3223 } | |
3224 | |
3225 // ANGLE only supports packed depth/stencil formats, so use it if it is | |
3226 // available. | |
3227 const bool depth24_stencil8_supported = | |
3228 feature_info_->feature_flags().packed_depth24_stencil8; | |
3229 VLOG(1) << "GL_OES_packed_depth_stencil " | |
3230 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3231 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3232 depth24_stencil8_supported) { | |
3233 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3234 offscreen_target_stencil_format_ = 0; | |
3235 } else { | |
3236 // It may be the case that this depth/stencil combination is not | |
3237 // supported, but this will be checked later by CheckFramebufferStatus. | |
3238 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3239 GL_DEPTH_COMPONENT16 : 0; | |
3240 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3241 GL_STENCIL_INDEX8 : 0; | |
3242 } | |
3243 } else { | |
3244 offscreen_target_color_format_ = | |
3245 offscreen_buffer_texture_needs_alpha || | |
3246 workarounds().disable_gl_rgb_format | |
3247 ? GL_RGBA | |
3248 : GL_RGB; | |
3249 | |
3250 // If depth is requested at all, use the packed depth stencil format if | |
3251 // it's available, as some desktop GL drivers don't support any non-packed | |
3252 // formats for depth attachments. | |
3253 const bool depth24_stencil8_supported = | |
3254 feature_info_->feature_flags().packed_depth24_stencil8; | |
3255 VLOG(1) << "GL_EXT_packed_depth_stencil " | |
3256 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3257 | |
3258 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3259 depth24_stencil8_supported) { | |
3260 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3261 offscreen_target_stencil_format_ = 0; | |
3262 } else { | |
3263 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3264 GL_DEPTH_COMPONENT : 0; | |
3265 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3266 GL_STENCIL_INDEX : 0; | |
3267 } | |
3268 } | |
3269 | |
3270 offscreen_saved_color_format_ = offscreen_buffer_texture_needs_alpha || | |
3271 workarounds().disable_gl_rgb_format | |
3272 ? GL_RGBA | |
3273 : GL_RGB; | |
3274 | |
3275 gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size; | |
3276 if (initial_size.IsEmpty()) { | 3377 if (initial_size.IsEmpty()) { |
3277 // If we're an offscreen surface with zero width and/or height, set to a | 3378 // If we're an offscreen surface with zero width and/or height, set to a |
3278 // non-zero size so that we have a complete framebuffer for operations | 3379 // non-zero size so that we have a complete framebuffer for operations |
3279 // like glClear. | 3380 // like glClear. |
3280 // TODO(piman): allow empty framebuffers, similar to | 3381 // TODO(piman): allow empty framebuffers, similar to |
3281 // EGL_KHR_surfaceless_context / GL_OES_surfaceless_context. | 3382 // EGL_KHR_surfaceless_context / GL_OES_surfaceless_context. |
3282 initial_size = gfx::Size(1, 1); | 3383 initial_size = gfx::Size(1, 1); |
3283 } | 3384 } |
3284 | 3385 |
3285 state_.viewport_width = initial_size.width(); | 3386 state_.viewport_width = initial_size.width(); |
3286 state_.viewport_height = initial_size.height(); | 3387 state_.viewport_height = initial_size.height(); |
3287 } else { | 3388 } else { |
3288 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); | |
3289 // These are NOT if the back buffer has these proprorties. They are | |
3290 // if we want the command buffer to enforce them regardless of what | |
3291 // the real backbuffer is assuming the real back buffer gives us more than | |
3292 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll | |
3293 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we | |
3294 // can't do anything about that. | |
3295 | |
3296 if (!surfaceless_) { | |
3297 GLint depth_bits = 0; | |
3298 GLint stencil_bits = 0; | |
3299 | |
3300 bool default_fb = (GetBackbufferServiceId() == 0); | |
3301 | |
3302 if (gl_version_info().is_desktop_core_profile) { | |
3303 glGetFramebufferAttachmentParameterivEXT( | |
3304 GL_FRAMEBUFFER, | |
3305 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, | |
3306 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); | |
3307 glGetFramebufferAttachmentParameterivEXT( | |
3308 GL_FRAMEBUFFER, | |
3309 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, | |
3310 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); | |
3311 glGetFramebufferAttachmentParameterivEXT( | |
3312 GL_FRAMEBUFFER, | |
3313 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, | |
3314 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); | |
3315 } else { | |
3316 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); | |
3317 glGetIntegerv(GL_DEPTH_BITS, &depth_bits); | |
3318 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); | |
3319 } | |
3320 | |
3321 // This checks if the user requested RGBA and we have RGBA then RGBA. If | |
3322 // the user requested RGB then RGB. If the user did not specify a | |
3323 // preference than use whatever we were given. Same for DEPTH and STENCIL. | |
3324 back_buffer_color_format_ = | |
3325 (attrib_helper.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; | |
3326 back_buffer_has_depth_ = attrib_helper.depth_size != 0 && depth_bits > 0; | |
3327 back_buffer_has_stencil_ = | |
3328 attrib_helper.stencil_size != 0 && stencil_bits > 0; | |
3329 } | |
3330 | |
3331 state_.viewport_width = surface->GetSize().width(); | 3389 state_.viewport_width = surface->GetSize().width(); |
3332 state_.viewport_height = surface->GetSize().height(); | 3390 state_.viewport_height = surface->GetSize().height(); |
3333 } | 3391 } |
3334 | 3392 |
3335 // OpenGL ES 2.0 implicitly enables the desktop GL capability | 3393 // OpenGL ES 2.0 implicitly enables the desktop GL capability |
3336 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact | 3394 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact |
3337 // isn't well documented; it was discovered in the Khronos OpenGL ES | 3395 // isn't well documented; it was discovered in the Khronos OpenGL ES |
3338 // mailing list archives. It also implicitly enables the desktop GL | 3396 // mailing list archives. It also implicitly enables the desktop GL |
3339 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord | 3397 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord |
3340 // variable in fragment shaders. | 3398 // variable in fragment shaders. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3459 | 3517 |
3460 // Clear the backbuffer. | 3518 // Clear the backbuffer. |
3461 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 3519 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
3462 | 3520 |
3463 // Restore alpha clear value if we changed it. | 3521 // Restore alpha clear value if we changed it. |
3464 if (clear_alpha) { | 3522 if (clear_alpha) { |
3465 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 3523 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
3466 } | 3524 } |
3467 } | 3525 } |
3468 | 3526 |
3469 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer(); | 3527 ApplySurfaceFeatures(); |
3470 if (workarounds() | |
3471 .disable_post_sub_buffers_for_onscreen_surfaces && | |
3472 !surface->IsOffscreen()) | |
3473 supports_post_sub_buffer_ = false; | |
3474 | |
3475 supports_swap_buffers_with_damage_ = surface->SupportsSwapBuffersWithDamage(); | |
3476 | |
3477 supports_commit_overlay_planes_ = surface->SupportsCommitOverlayPlanes(); | |
3478 | |
3479 supports_async_swap_ = surface->SupportsAsyncSwap(); | |
3480 | 3528 |
3481 if (workarounds().reverse_point_sprite_coord_origin) { | 3529 if (workarounds().reverse_point_sprite_coord_origin) { |
3482 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); | 3530 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); |
3483 } | 3531 } |
3484 | 3532 |
3485 if (workarounds().unbind_fbo_on_context_switch) { | 3533 if (workarounds().unbind_fbo_on_context_switch) { |
3486 context_->SetUnbindFboOnMakeCurrent(); | 3534 context_->SetUnbindFboOnMakeCurrent(); |
3487 } | 3535 } |
3488 | 3536 |
3489 if (workarounds().gl_clear_broken) { | 3537 if (workarounds().gl_clear_broken) { |
(...skipping 13440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16930 static const char kFunctionName[] = | 16978 static const char kFunctionName[] = |
16931 "glApplyScreenSpaceAntialiasingCHROMIUM"; | 16979 "glApplyScreenSpaceAntialiasingCHROMIUM"; |
16932 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) | 16980 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) |
16933 return; | 16981 return; |
16934 apply_framebuffer_attachment_cmaa_intel_ | 16982 apply_framebuffer_attachment_cmaa_intel_ |
16935 ->ApplyFramebufferAttachmentCMAAINTEL(this, bound_framebuffer, | 16983 ->ApplyFramebufferAttachmentCMAAINTEL(this, bound_framebuffer, |
16936 copy_texture_CHROMIUM_.get()); | 16984 copy_texture_CHROMIUM_.get()); |
16937 } | 16985 } |
16938 } | 16986 } |
16939 | 16987 |
16988 void GLES2DecoderImpl::DoSetSurfaceHandleCHROMIUM(GLint surface_handle) { | |
16989 #if defined(OS_ANDROID) | |
16990 if (surface_handle) { | |
16991 // Use the specified surface as a render target, and save decoder | |
16992 // state so that this can be reverted later. | |
16993 | |
16994 // We don't support switching between different surfaces. If you | |
16995 // need this, you have to make a call with surface_handle=0 in | |
16996 // between. | |
16997 if (!surface_->IsOffscreen()) { | |
16998 LOCAL_SET_GL_ERROR( | |
16999 GL_INVALID_OPERATION, | |
17000 "glSetSurfaceHandleCHROMIUM", | |
17001 "Current surface is not offscreen, cannot redirect drawing"); | |
17002 return; | |
17003 } | |
17004 | |
17005 // One-time initialization when first activating a direct draw surface. | |
17006 ANativeWindow* window = | |
17007 gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( | |
17008 surface_handle); | |
17009 if (!window) { | |
17010 LOCAL_SET_GL_ERROR( | |
17011 GL_INVALID_OPERATION, | |
17012 "glSetSurfaceHandleCHROMIUM", | |
17013 "Could not acquire a window for this surface handle"); | |
17014 return; | |
17015 } | |
17016 | |
17017 direct_render_state_.reset(new DirectRenderState()); | |
17018 direct_render_state_->direct_surface = | |
17019 new gl::NativeViewGLSurfaceEGL(window); | |
17020 | |
17021 // It would be useful if we could get a custom surface format such | |
17022 // as one with a depth buffer here, but the new surface must use | |
17023 // the same format as the one originally used for creating the GL | |
17024 // context. Anything else just results in BAD_MATCH errors. | |
17025 bool initialize_success = direct_render_state_->direct_surface->Initialize( | |
17026 surface_->GetFormat()); | |
17027 if (!initialize_success) { | |
17028 LOG(ERROR) << "Direct render surface init failed for handle " << | |
17029 surface_handle; | |
17030 } | |
17031 ANativeWindow_release(window); | |
17032 | |
17033 direct_render_state_->orig_surface = surface_; | |
17034 | |
17035 // Offscreen surfaces don't support SwapBuffers, make sure it's not | |
17036 // considered offscreen. Various code in this file checks for is_offscreen | |
17037 // = !!offscreen_target_frame_buffer_.get(). | |
17038 direct_render_state_->orig_offscreen_target_frame_buffer = | |
17039 std::move(offscreen_target_frame_buffer_); | |
17040 offscreen_target_frame_buffer_.reset(nullptr); | |
17041 | |
17042 // Activate the surface. This does *not* rebind the active framebuffer, | |
17043 // callers must do so themselves as needed. | |
17044 SetSurface(direct_render_state_->direct_surface); | |
17045 ApplySurfaceAttributesAndGetAlphaBits(false, attrib_helper_); | |
17046 ApplySurfaceFeatures(); | |
17047 | |
17048 // If we're using the default draw framebuffer, make the surface current. | |
17049 if (!framebuffer_state_.bound_draw_framebuffer.get()) { | |
17050 context_->MakeCurrent(surface_.get()); | |
piman
2016/11/09 22:26:09
You need to do the MakeCurrent before the ApplySur
klausw
2016/11/10 02:28:07
Done, I was misunderstanding how MakeCurrent inter
| |
17051 // This is a new surface, so MakeCurrent resets viewport and scissor | |
17052 // dimensions. Re-apply the settings from the current state. | |
piman
2016/11/09 22:26:09
Actually, MakeCurrent only sets viewport/scissor o
klausw
2016/11/10 02:28:08
Done.
| |
17053 glViewport(state_.viewport_x, state_.viewport_y, | |
17054 state_.viewport_width, state_.viewport_height); | |
17055 glScissor(state_.scissor_x, | |
17056 state_.scissor_y, | |
17057 state_.scissor_width, | |
17058 state_.scissor_height); | |
17059 | |
17060 // DoReadBuffer and DoDrawBuffersEXT may have modified bindings. | |
17061 // We don't care for modifications to a user-bound framebuffer | |
17062 // since those will still be valid. Target GL_NONE also remains | |
17063 // valid, so we just need to undo the GL_BACK -> | |
17064 // GL_COLOR_ATTACHMENT0 mapping. Caveat: the current buffer | |
17065 // content is not preserved across this surface switch. | |
17066 if (back_buffer_read_buffer_ == GL_BACK) { | |
17067 glReadBuffer(GL_BACK); | |
17068 } | |
17069 if (back_buffer_draw_buffer_ == GL_BACK) { | |
17070 GLenum buf = GL_BACK; | |
17071 glDrawBuffersARB(1, &buf); | |
17072 } | |
17073 } | |
17074 } else { | |
17075 // Restore original state for drawing offscreen. | |
17076 | |
17077 // Ignore redundant calls. | |
17078 if (!direct_render_state_) { | |
17079 LOCAL_SET_GL_ERROR( | |
17080 GL_INVALID_OPERATION, | |
17081 "glSetSurfaceHandleCHROMIUM", | |
17082 "Surface was not set by glSetSurfaceHandleCHROMIUM, cannot unset"); | |
17083 } | |
17084 | |
17085 offscreen_target_frame_buffer_ = | |
17086 std::move(direct_render_state_->orig_offscreen_target_frame_buffer); | |
17087 | |
17088 SetSurface(direct_render_state_->orig_surface); | |
17089 ApplySurfaceAttributesAndGetAlphaBits(true, attrib_helper_); | |
piman
2016/11/09 22:26:10
You probably want to MakeCurrent here to the offsc
klausw
2016/11/10 02:28:07
Done.
| |
17090 ApplySurfaceFeatures(); | |
17091 | |
17092 // The viewport size may have been changed, resize it. | |
17093 if (!ResizeOffscreenFramebuffer( | |
17094 gfx::Size(state_.viewport_width, state_.viewport_height))) { | |
piman
2016/11/09 22:26:09
You want to use offscreen_size_, not the viewport
klausw
2016/11/10 02:28:07
Changed, I think the most intuitive behavior would
| |
17095 LOCAL_SET_GL_ERROR( | |
17096 GL_INVALID_OPERATION, | |
17097 "glSetSurfaceHandleCHROMIUM", | |
17098 "Failed to resize offscreen framebuffer"); | |
17099 } | |
17100 | |
17101 // If we're using the default draw framebuffer, fix things. | |
17102 if (!framebuffer_state_.bound_draw_framebuffer.get()) { | |
17103 // DoDrawBuffersEXT: remap GL_BACK to GL_COLOR_ATTACHMENT0. | |
17104 if (back_buffer_read_buffer_ == GL_BACK) { | |
17105 glReadBuffer(GL_COLOR_ATTACHMENT0); | |
17106 } | |
17107 if (back_buffer_draw_buffer_ == GL_BACK) { | |
17108 GLenum buf = GL_COLOR_ATTACHMENT0; | |
17109 glDrawBuffersARB(1, &buf); | |
17110 } | |
17111 } | |
17112 | |
17113 // Trust the state struct's destructors to handle refcounting for | |
17114 // surfaces and trigger apprpriate cleanup. | |
17115 direct_render_state_.reset(); | |
17116 } | |
17117 #else // !OS_ANDROID | |
17118 LOCAL_SET_GL_ERROR( | |
17119 GL_INVALID_OPERATION, | |
17120 "glSetSurfaceHandleCHROMIUM", | |
17121 "Direct render surface is unsupported on this platform"); | |
17122 #endif | |
17123 } | |
17124 | |
16940 void GLES2DecoderImpl::DoInsertEventMarkerEXT( | 17125 void GLES2DecoderImpl::DoInsertEventMarkerEXT( |
16941 GLsizei length, const GLchar* marker) { | 17126 GLsizei length, const GLchar* marker) { |
16942 if (!marker) { | 17127 if (!marker) { |
16943 marker = ""; | 17128 marker = ""; |
16944 } | 17129 } |
16945 debug_marker_manager_.SetMarker( | 17130 debug_marker_manager_.SetMarker( |
16946 length ? std::string(marker, length) : std::string(marker)); | 17131 length ? std::string(marker, length) : std::string(marker)); |
16947 } | 17132 } |
16948 | 17133 |
16949 void GLES2DecoderImpl::DoPushGroupMarkerEXT( | 17134 void GLES2DecoderImpl::DoPushGroupMarkerEXT( |
(...skipping 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
18796 } | 18981 } |
18797 | 18982 |
18798 // Include the auto-generated part of this file. We split this because it means | 18983 // Include the auto-generated part of this file. We split this because it means |
18799 // we can easily edit the non-auto generated parts right here in this file | 18984 // we can easily edit the non-auto generated parts right here in this file |
18800 // instead of having to edit some template or the code generator. | 18985 // instead of having to edit some template or the code generator. |
18801 #include "base/macros.h" | 18986 #include "base/macros.h" |
18802 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 18987 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
18803 | 18988 |
18804 } // namespace gles2 | 18989 } // namespace gles2 |
18805 } // namespace gpu | 18990 } // namespace gpu |
OLD | NEW |