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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 | 1038 |
1033 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, | 1039 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, |
1034 const volatile GLfloat* matrix); | 1040 const volatile GLfloat* matrix); |
1035 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); | 1041 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); |
1036 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, | 1042 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, |
1037 const volatile GLuint* textures); | 1043 const volatile GLuint* textures); |
1038 | 1044 |
1039 void DoFlushMappedBufferRange( | 1045 void DoFlushMappedBufferRange( |
1040 GLenum target, GLintptr offset, GLsizeiptr size); | 1046 GLenum target, GLintptr offset, GLsizeiptr size); |
1041 | 1047 |
| 1048 void DoSetSurfaceHandleCHROMIUM(GLint surface_handle); |
| 1049 |
| 1050 // Apply creation attibutes such as depth_bits for the offscreen |
| 1051 // framebuffer or active surface as applicable. |
| 1052 GLint ApplySurfaceAttributesAndGetAlphaBits( |
| 1053 bool offscreen, const ContextCreationAttribHelper& attrib_helper); |
| 1054 |
| 1055 // Apply feature flags and surface-specific workarounds to match the |
| 1056 // capabilities of the current surface. Used by Initialize() and |
| 1057 // DoSetSurfaceHandleCHROMIUM. |
| 1058 void ApplySurfaceFeatures(); |
| 1059 |
1042 // Creates a Program for the given program. | 1060 // Creates a Program for the given program. |
1043 Program* CreateProgram(GLuint client_id, GLuint service_id) { | 1061 Program* CreateProgram(GLuint client_id, GLuint service_id) { |
1044 return program_manager()->CreateProgram(client_id, service_id); | 1062 return program_manager()->CreateProgram(client_id, service_id); |
1045 } | 1063 } |
1046 | 1064 |
1047 // Gets the program info for the given program. Returns NULL if none exists. | 1065 // Gets the program info for the given program. Returns NULL if none exists. |
1048 Program* GetProgram(GLuint client_id) { | 1066 Program* GetProgram(GLuint client_id) { |
1049 return program_manager()->GetProgram(client_id); | 1067 return program_manager()->GetProgram(client_id); |
1050 } | 1068 } |
1051 | 1069 |
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2172 Error Handle##name(uint32_t immediate_data_size, const volatile void* data); | 2190 Error Handle##name(uint32_t immediate_data_size, const volatile void* data); |
2173 | 2191 |
2174 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 2192 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
2175 | 2193 |
2176 #undef GLES2_CMD_OP | 2194 #undef GLES2_CMD_OP |
2177 | 2195 |
2178 // The GL context this decoder renders to on behalf of the client. | 2196 // The GL context this decoder renders to on behalf of the client. |
2179 scoped_refptr<gl::GLSurface> surface_; | 2197 scoped_refptr<gl::GLSurface> surface_; |
2180 scoped_refptr<gl::GLContext> context_; | 2198 scoped_refptr<gl::GLContext> context_; |
2181 | 2199 |
| 2200 ContextCreationAttribHelper attrib_helper_; |
| 2201 |
| 2202 // Direct render mode data for switching and restoring the |
| 2203 // underlying destination surface, cf. DoSetSurfaceHandleCHROMIUM. |
| 2204 struct DirectRenderState{ |
| 2205 scoped_refptr<gl::GLSurface> direct_surface; |
| 2206 scoped_refptr<gl::GLSurface> orig_surface; |
| 2207 std::unique_ptr<BackFramebuffer> orig_offscreen_target_frame_buffer; |
| 2208 }; |
| 2209 std::unique_ptr<DirectRenderState> direct_render_state_; |
| 2210 |
2182 // The ContextGroup for this decoder uses to track resources. | 2211 // The ContextGroup for this decoder uses to track resources. |
2183 scoped_refptr<ContextGroup> group_; | 2212 scoped_refptr<ContextGroup> group_; |
2184 | 2213 |
2185 DebugMarkerManager debug_marker_manager_; | 2214 DebugMarkerManager debug_marker_manager_; |
2186 Logger logger_; | 2215 Logger logger_; |
2187 | 2216 |
2188 // All the state for this context. | 2217 // All the state for this context. |
2189 ContextState state_; | 2218 ContextState state_; |
2190 | 2219 |
2191 std::unique_ptr<TransformFeedbackManager> transform_feedback_manager_; | 2220 std::unique_ptr<TransformFeedbackManager> transform_feedback_manager_; |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 validation_fbo_multisample_(0), | 3072 validation_fbo_multisample_(0), |
3044 validation_fbo_(0), | 3073 validation_fbo_(0), |
3045 texture_manager_service_id_generation_(0), | 3074 texture_manager_service_id_generation_(0), |
3046 force_shader_name_hashing_for_test(false) { | 3075 force_shader_name_hashing_for_test(false) { |
3047 DCHECK(group); | 3076 DCHECK(group); |
3048 } | 3077 } |
3049 | 3078 |
3050 GLES2DecoderImpl::~GLES2DecoderImpl() { | 3079 GLES2DecoderImpl::~GLES2DecoderImpl() { |
3051 } | 3080 } |
3052 | 3081 |
| 3082 GLint GLES2DecoderImpl::ApplySurfaceAttributesAndGetAlphaBits( |
| 3083 bool offscreen, const ContextCreationAttribHelper& attrib_helper) { |
| 3084 GLint alpha_bits = 0; |
| 3085 |
| 3086 if (offscreen) { |
| 3087 offscreen_buffer_should_have_alpha_ = attrib_helper.alpha_size > 0; |
| 3088 |
| 3089 // Whether the offscreen buffer texture should have an alpha channel. Does |
| 3090 // not include logic from workarounds. |
| 3091 bool offscreen_buffer_texture_needs_alpha = |
| 3092 offscreen_buffer_should_have_alpha_ || |
| 3093 (ChromiumImageNeedsRGBEmulation() && |
| 3094 attrib_helper.should_use_native_gmb_for_backbuffer); |
| 3095 |
| 3096 if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 && |
| 3097 features().chromium_framebuffer_multisample) { |
| 3098 // Per ext_framebuffer_multisample spec, need max bound on sample count. |
| 3099 // max_sample_count must be initialized to a sane value. If |
| 3100 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. |
| 3101 GLint max_sample_count = 1; |
| 3102 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); |
| 3103 offscreen_target_samples_ = std::min(attrib_helper.samples, |
| 3104 max_sample_count); |
| 3105 } else { |
| 3106 offscreen_target_samples_ = 1; |
| 3107 } |
| 3108 offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved; |
| 3109 |
| 3110 if (gl_version_info().is_es) { |
| 3111 const bool rgb8_supported = context_->HasExtension("GL_OES_rgb8_rgba8"); |
| 3112 // The only available default render buffer formats in GLES2 have very |
| 3113 // little precision. Don't enable multisampling unless 8-bit render |
| 3114 // buffer formats are available--instead fall back to 8-bit textures. |
| 3115 if (rgb8_supported && offscreen_target_samples_ > 1) { |
| 3116 offscreen_target_color_format_ = |
| 3117 offscreen_buffer_texture_needs_alpha ? GL_RGBA8 : GL_RGB8; |
| 3118 } else { |
| 3119 offscreen_target_samples_ = 1; |
| 3120 offscreen_target_color_format_ = |
| 3121 offscreen_buffer_texture_needs_alpha || |
| 3122 workarounds().disable_gl_rgb_format |
| 3123 ? GL_RGBA |
| 3124 : GL_RGB; |
| 3125 } |
| 3126 |
| 3127 // ANGLE only supports packed depth/stencil formats, so use it if it is |
| 3128 // available. |
| 3129 const bool depth24_stencil8_supported = |
| 3130 feature_info_->feature_flags().packed_depth24_stencil8; |
| 3131 VLOG(1) << "GL_OES_packed_depth_stencil " |
| 3132 << (depth24_stencil8_supported ? "" : "not ") << "supported."; |
| 3133 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && |
| 3134 depth24_stencil8_supported) { |
| 3135 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; |
| 3136 offscreen_target_stencil_format_ = 0; |
| 3137 } else { |
| 3138 // It may be the case that this depth/stencil combination is not |
| 3139 // supported, but this will be checked later by CheckFramebufferStatus. |
| 3140 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? |
| 3141 GL_DEPTH_COMPONENT16 : 0; |
| 3142 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? |
| 3143 GL_STENCIL_INDEX8 : 0; |
| 3144 } |
| 3145 } else { |
| 3146 offscreen_target_color_format_ = |
| 3147 offscreen_buffer_texture_needs_alpha || |
| 3148 workarounds().disable_gl_rgb_format |
| 3149 ? GL_RGBA |
| 3150 : GL_RGB; |
| 3151 |
| 3152 // If depth is requested at all, use the packed depth stencil format if |
| 3153 // it's available, as some desktop GL drivers don't support any non-packed |
| 3154 // formats for depth attachments. |
| 3155 const bool depth24_stencil8_supported = |
| 3156 feature_info_->feature_flags().packed_depth24_stencil8; |
| 3157 VLOG(1) << "GL_EXT_packed_depth_stencil " |
| 3158 << (depth24_stencil8_supported ? "" : "not ") << "supported."; |
| 3159 |
| 3160 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && |
| 3161 depth24_stencil8_supported) { |
| 3162 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; |
| 3163 offscreen_target_stencil_format_ = 0; |
| 3164 } else { |
| 3165 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? |
| 3166 GL_DEPTH_COMPONENT : 0; |
| 3167 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? |
| 3168 GL_STENCIL_INDEX : 0; |
| 3169 } |
| 3170 } |
| 3171 |
| 3172 offscreen_saved_color_format_ = offscreen_buffer_texture_needs_alpha || |
| 3173 workarounds().disable_gl_rgb_format |
| 3174 ? GL_RGBA |
| 3175 : GL_RGB; |
| 3176 } else { |
| 3177 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); |
| 3178 // These are NOT if the back buffer has these proprorties. They are |
| 3179 // if we want the command buffer to enforce them regardless of what |
| 3180 // the real backbuffer is assuming the real back buffer gives us more than |
| 3181 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll |
| 3182 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we |
| 3183 // can't do anything about that. |
| 3184 |
| 3185 if (!surfaceless_) { |
| 3186 GLint depth_bits = 0; |
| 3187 GLint stencil_bits = 0; |
| 3188 |
| 3189 bool default_fb = (GetBackbufferServiceId() == 0); |
| 3190 |
| 3191 if (gl_version_info().is_desktop_core_profile) { |
| 3192 glGetFramebufferAttachmentParameterivEXT( |
| 3193 GL_FRAMEBUFFER, |
| 3194 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, |
| 3195 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); |
| 3196 glGetFramebufferAttachmentParameterivEXT( |
| 3197 GL_FRAMEBUFFER, |
| 3198 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, |
| 3199 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); |
| 3200 glGetFramebufferAttachmentParameterivEXT( |
| 3201 GL_FRAMEBUFFER, |
| 3202 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, |
| 3203 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); |
| 3204 } else { |
| 3205 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); |
| 3206 glGetIntegerv(GL_DEPTH_BITS, &depth_bits); |
| 3207 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); |
| 3208 } |
| 3209 |
| 3210 // This checks if the user requested RGBA and we have RGBA then RGBA. If |
| 3211 // the user requested RGB then RGB. If the user did not specify a |
| 3212 // preference than use whatever we were given. Same for DEPTH and STENCIL. |
| 3213 back_buffer_color_format_ = |
| 3214 (attrib_helper.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; |
| 3215 back_buffer_has_depth_ = attrib_helper.depth_size != 0 && depth_bits > 0; |
| 3216 back_buffer_has_stencil_ = |
| 3217 attrib_helper.stencil_size != 0 && stencil_bits > 0; |
| 3218 } |
| 3219 } |
| 3220 |
| 3221 return alpha_bits; |
| 3222 } |
| 3223 |
| 3224 void GLES2DecoderImpl::ApplySurfaceFeatures() { |
| 3225 supports_post_sub_buffer_ = surface_->SupportsPostSubBuffer(); |
| 3226 if (workarounds() |
| 3227 .disable_post_sub_buffers_for_onscreen_surfaces && |
| 3228 !surface_->IsOffscreen()) |
| 3229 supports_post_sub_buffer_ = false; |
| 3230 |
| 3231 supports_swap_buffers_with_damage_ = |
| 3232 surface_->SupportsSwapBuffersWithDamage(); |
| 3233 |
| 3234 supports_commit_overlay_planes_ = surface_->SupportsCommitOverlayPlanes(); |
| 3235 |
| 3236 supports_async_swap_ = surface_->SupportsAsyncSwap(); |
| 3237 } |
| 3238 |
3053 bool GLES2DecoderImpl::Initialize( | 3239 bool GLES2DecoderImpl::Initialize( |
3054 const scoped_refptr<gl::GLSurface>& surface, | 3240 const scoped_refptr<gl::GLSurface>& surface, |
3055 const scoped_refptr<gl::GLContext>& context, | 3241 const scoped_refptr<gl::GLContext>& context, |
3056 bool offscreen, | 3242 bool offscreen, |
3057 const DisallowedFeatures& disallowed_features, | 3243 const DisallowedFeatures& disallowed_features, |
3058 const ContextCreationAttribHelper& attrib_helper) { | 3244 const ContextCreationAttribHelper& attrib_helper) { |
3059 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); | 3245 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); |
3060 DCHECK(context->IsCurrent(surface.get())); | 3246 DCHECK(context->IsCurrent(surface.get())); |
3061 DCHECK(!context_.get()); | 3247 DCHECK(!context_.get()); |
3062 | 3248 |
| 3249 // Save the attrib helper data for future use in ApplySurfaceFeatures. |
| 3250 attrib_helper_ = attrib_helper; |
| 3251 |
3063 surfaceless_ = surface->IsSurfaceless() && !offscreen; | 3252 surfaceless_ = surface->IsSurfaceless() && !offscreen; |
3064 | 3253 |
3065 set_initialized(); | 3254 set_initialized(); |
3066 gpu_state_tracer_ = GPUStateTracer::Create(&state_); | 3255 gpu_state_tracer_ = GPUStateTracer::Create(&state_); |
3067 | 3256 |
3068 if (group_->gpu_preferences().enable_gpu_debugging) | 3257 if (group_->gpu_preferences().enable_gpu_debugging) |
3069 set_debug(true); | 3258 set_debug(true); |
3070 | 3259 |
3071 if (group_->gpu_preferences().enable_gpu_command_logging) | 3260 if (group_->gpu_preferences().enable_gpu_command_logging) |
3072 set_log_commands(true); | 3261 set_log_commands(true); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3225 state_.texture_units[tt].bound_texture_cube_map = ref; | 3414 state_.texture_units[tt].bound_texture_cube_map = ref; |
3226 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); | 3415 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); |
3227 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); | 3416 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); |
3228 state_.texture_units[tt].bound_texture_2d = ref; | 3417 state_.texture_units[tt].bound_texture_2d = ref; |
3229 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); | 3418 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); |
3230 } | 3419 } |
3231 glActiveTexture(GL_TEXTURE0); | 3420 glActiveTexture(GL_TEXTURE0); |
3232 CHECK_GL_ERROR(); | 3421 CHECK_GL_ERROR(); |
3233 | 3422 |
3234 // cache ALPHA_BITS result for re-use with clear behaviour | 3423 // cache ALPHA_BITS result for re-use with clear behaviour |
3235 GLint alpha_bits = 0; | 3424 GLint alpha_bits = ApplySurfaceAttributesAndGetAlphaBits( |
| 3425 offscreen, attrib_helper); |
3236 | 3426 |
3237 if (offscreen) { | 3427 if (offscreen) { |
3238 offscreen_buffer_should_have_alpha_ = attrib_helper.alpha_size > 0; | 3428 gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size; |
3239 | 3429 |
3240 // Whether the offscreen buffer texture should have an alpha channel. Does | |
3241 // not include logic from workarounds. | |
3242 bool offscreen_buffer_texture_needs_alpha = | |
3243 offscreen_buffer_should_have_alpha_ || | |
3244 (ChromiumImageNeedsRGBEmulation() && | |
3245 attrib_helper.should_use_native_gmb_for_backbuffer); | |
3246 | |
3247 if (attrib_helper.samples > 0 && attrib_helper.sample_buffers > 0 && | |
3248 features().chromium_framebuffer_multisample) { | |
3249 // Per ext_framebuffer_multisample spec, need max bound on sample count. | |
3250 // max_sample_count must be initialized to a sane value. If | |
3251 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. | |
3252 GLint max_sample_count = 1; | |
3253 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); | |
3254 offscreen_target_samples_ = std::min(attrib_helper.samples, | |
3255 max_sample_count); | |
3256 } else { | |
3257 offscreen_target_samples_ = 1; | |
3258 } | |
3259 offscreen_target_buffer_preserved_ = attrib_helper.buffer_preserved; | |
3260 | |
3261 if (gl_version_info().is_es) { | |
3262 const bool rgb8_supported = context_->HasExtension("GL_OES_rgb8_rgba8"); | |
3263 // The only available default render buffer formats in GLES2 have very | |
3264 // little precision. Don't enable multisampling unless 8-bit render | |
3265 // buffer formats are available--instead fall back to 8-bit textures. | |
3266 if (rgb8_supported && offscreen_target_samples_ > 1) { | |
3267 offscreen_target_color_format_ = | |
3268 offscreen_buffer_texture_needs_alpha ? GL_RGBA8 : GL_RGB8; | |
3269 } else { | |
3270 offscreen_target_samples_ = 1; | |
3271 offscreen_target_color_format_ = | |
3272 offscreen_buffer_texture_needs_alpha || | |
3273 workarounds().disable_gl_rgb_format | |
3274 ? GL_RGBA | |
3275 : GL_RGB; | |
3276 } | |
3277 | |
3278 // ANGLE only supports packed depth/stencil formats, so use it if it is | |
3279 // available. | |
3280 const bool depth24_stencil8_supported = | |
3281 feature_info_->feature_flags().packed_depth24_stencil8; | |
3282 VLOG(1) << "GL_OES_packed_depth_stencil " | |
3283 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3284 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3285 depth24_stencil8_supported) { | |
3286 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3287 offscreen_target_stencil_format_ = 0; | |
3288 } else { | |
3289 // It may be the case that this depth/stencil combination is not | |
3290 // supported, but this will be checked later by CheckFramebufferStatus. | |
3291 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3292 GL_DEPTH_COMPONENT16 : 0; | |
3293 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3294 GL_STENCIL_INDEX8 : 0; | |
3295 } | |
3296 } else { | |
3297 offscreen_target_color_format_ = | |
3298 offscreen_buffer_texture_needs_alpha || | |
3299 workarounds().disable_gl_rgb_format | |
3300 ? GL_RGBA | |
3301 : GL_RGB; | |
3302 | |
3303 // If depth is requested at all, use the packed depth stencil format if | |
3304 // it's available, as some desktop GL drivers don't support any non-packed | |
3305 // formats for depth attachments. | |
3306 const bool depth24_stencil8_supported = | |
3307 feature_info_->feature_flags().packed_depth24_stencil8; | |
3308 VLOG(1) << "GL_EXT_packed_depth_stencil " | |
3309 << (depth24_stencil8_supported ? "" : "not ") << "supported."; | |
3310 | |
3311 if ((attrib_helper.depth_size > 0 || attrib_helper.stencil_size > 0) && | |
3312 depth24_stencil8_supported) { | |
3313 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; | |
3314 offscreen_target_stencil_format_ = 0; | |
3315 } else { | |
3316 offscreen_target_depth_format_ = attrib_helper.depth_size > 0 ? | |
3317 GL_DEPTH_COMPONENT : 0; | |
3318 offscreen_target_stencil_format_ = attrib_helper.stencil_size > 0 ? | |
3319 GL_STENCIL_INDEX : 0; | |
3320 } | |
3321 } | |
3322 | |
3323 offscreen_saved_color_format_ = offscreen_buffer_texture_needs_alpha || | |
3324 workarounds().disable_gl_rgb_format | |
3325 ? GL_RGBA | |
3326 : GL_RGB; | |
3327 | |
3328 gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size; | |
3329 if (initial_size.IsEmpty()) { | 3430 if (initial_size.IsEmpty()) { |
3330 // If we're an offscreen surface with zero width and/or height, set to a | 3431 // If we're an offscreen surface with zero width and/or height, set to a |
3331 // non-zero size so that we have a complete framebuffer for operations | 3432 // non-zero size so that we have a complete framebuffer for operations |
3332 // like glClear. | 3433 // like glClear. |
3333 // TODO(piman): allow empty framebuffers, similar to | 3434 // TODO(piman): allow empty framebuffers, similar to |
3334 // EGL_KHR_surfaceless_context / GL_OES_surfaceless_context. | 3435 // EGL_KHR_surfaceless_context / GL_OES_surfaceless_context. |
3335 initial_size = gfx::Size(1, 1); | 3436 initial_size = gfx::Size(1, 1); |
3336 } | 3437 } |
3337 | 3438 |
3338 state_.viewport_width = initial_size.width(); | 3439 state_.viewport_width = initial_size.width(); |
3339 state_.viewport_height = initial_size.height(); | 3440 state_.viewport_height = initial_size.height(); |
3340 } else { | 3441 } else { |
3341 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); | |
3342 // These are NOT if the back buffer has these proprorties. They are | |
3343 // if we want the command buffer to enforce them regardless of what | |
3344 // the real backbuffer is assuming the real back buffer gives us more than | |
3345 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll | |
3346 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we | |
3347 // can't do anything about that. | |
3348 | |
3349 if (!surfaceless_) { | |
3350 GLint depth_bits = 0; | |
3351 GLint stencil_bits = 0; | |
3352 | |
3353 bool default_fb = (GetBackbufferServiceId() == 0); | |
3354 | |
3355 if (gl_version_info().is_desktop_core_profile) { | |
3356 glGetFramebufferAttachmentParameterivEXT( | |
3357 GL_FRAMEBUFFER, | |
3358 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, | |
3359 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); | |
3360 glGetFramebufferAttachmentParameterivEXT( | |
3361 GL_FRAMEBUFFER, | |
3362 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, | |
3363 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); | |
3364 glGetFramebufferAttachmentParameterivEXT( | |
3365 GL_FRAMEBUFFER, | |
3366 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, | |
3367 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); | |
3368 } else { | |
3369 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); | |
3370 glGetIntegerv(GL_DEPTH_BITS, &depth_bits); | |
3371 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); | |
3372 } | |
3373 | |
3374 // This checks if the user requested RGBA and we have RGBA then RGBA. If | |
3375 // the user requested RGB then RGB. If the user did not specify a | |
3376 // preference than use whatever we were given. Same for DEPTH and STENCIL. | |
3377 back_buffer_color_format_ = | |
3378 (attrib_helper.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; | |
3379 back_buffer_has_depth_ = attrib_helper.depth_size != 0 && depth_bits > 0; | |
3380 back_buffer_has_stencil_ = | |
3381 attrib_helper.stencil_size != 0 && stencil_bits > 0; | |
3382 } | |
3383 | |
3384 state_.viewport_width = surface->GetSize().width(); | 3442 state_.viewport_width = surface->GetSize().width(); |
3385 state_.viewport_height = surface->GetSize().height(); | 3443 state_.viewport_height = surface->GetSize().height(); |
3386 } | 3444 } |
3387 | 3445 |
3388 // OpenGL ES 2.0 implicitly enables the desktop GL capability | 3446 // OpenGL ES 2.0 implicitly enables the desktop GL capability |
3389 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact | 3447 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact |
3390 // isn't well documented; it was discovered in the Khronos OpenGL ES | 3448 // isn't well documented; it was discovered in the Khronos OpenGL ES |
3391 // mailing list archives. It also implicitly enables the desktop GL | 3449 // mailing list archives. It also implicitly enables the desktop GL |
3392 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord | 3450 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord |
3393 // variable in fragment shaders. | 3451 // variable in fragment shaders. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3514 | 3572 |
3515 // Clear the backbuffer. | 3573 // Clear the backbuffer. |
3516 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 3574 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
3517 | 3575 |
3518 // Restore alpha clear value if we changed it. | 3576 // Restore alpha clear value if we changed it. |
3519 if (clear_alpha) { | 3577 if (clear_alpha) { |
3520 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 3578 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
3521 } | 3579 } |
3522 } | 3580 } |
3523 | 3581 |
3524 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer(); | 3582 ApplySurfaceFeatures(); |
3525 if (workarounds() | |
3526 .disable_post_sub_buffers_for_onscreen_surfaces && | |
3527 !surface->IsOffscreen()) | |
3528 supports_post_sub_buffer_ = false; | |
3529 | |
3530 supports_swap_buffers_with_damage_ = surface->SupportsSwapBuffersWithDamage(); | |
3531 | |
3532 supports_commit_overlay_planes_ = surface->SupportsCommitOverlayPlanes(); | |
3533 | |
3534 supports_async_swap_ = surface->SupportsAsyncSwap(); | |
3535 | 3583 |
3536 if (workarounds().reverse_point_sprite_coord_origin) { | 3584 if (workarounds().reverse_point_sprite_coord_origin) { |
3537 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); | 3585 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); |
3538 } | 3586 } |
3539 | 3587 |
3540 if (workarounds().unbind_fbo_on_context_switch) { | 3588 if (workarounds().unbind_fbo_on_context_switch) { |
3541 context_->SetUnbindFboOnMakeCurrent(); | 3589 context_->SetUnbindFboOnMakeCurrent(); |
3542 } | 3590 } |
3543 | 3591 |
3544 if (workarounds().gl_clear_broken) { | 3592 if (workarounds().gl_clear_broken) { |
(...skipping 13709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17254 static const char kFunctionName[] = | 17302 static const char kFunctionName[] = |
17255 "glApplyScreenSpaceAntialiasingCHROMIUM"; | 17303 "glApplyScreenSpaceAntialiasingCHROMIUM"; |
17256 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) | 17304 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) |
17257 return; | 17305 return; |
17258 apply_framebuffer_attachment_cmaa_intel_ | 17306 apply_framebuffer_attachment_cmaa_intel_ |
17259 ->ApplyFramebufferAttachmentCMAAINTEL(this, bound_framebuffer, | 17307 ->ApplyFramebufferAttachmentCMAAINTEL(this, bound_framebuffer, |
17260 copy_texture_CHROMIUM_.get()); | 17308 copy_texture_CHROMIUM_.get()); |
17261 } | 17309 } |
17262 } | 17310 } |
17263 | 17311 |
| 17312 void GLES2DecoderImpl::DoSetSurfaceHandleCHROMIUM(GLint surface_handle) { |
| 17313 #if defined(OS_ANDROID) |
| 17314 if (surface_handle) { |
| 17315 // Use the specified surface as a render target, and save decoder |
| 17316 // state so that this can be reverted later. |
| 17317 |
| 17318 // We don't support switching between different surfaces. If you |
| 17319 // need this, you have to make a call with surface_handle=0 in |
| 17320 // between. |
| 17321 if (!surface_->IsOffscreen()) { |
| 17322 LOCAL_SET_GL_ERROR( |
| 17323 GL_INVALID_OPERATION, |
| 17324 "glSetSurfaceHandleCHROMIUM", |
| 17325 "Current surface is not offscreen, cannot redirect drawing"); |
| 17326 return; |
| 17327 } |
| 17328 |
| 17329 // One-time initialization when first activating a direct draw surface. |
| 17330 ANativeWindow* window = |
| 17331 gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( |
| 17332 surface_handle); |
| 17333 if (!window) { |
| 17334 LOCAL_SET_GL_ERROR( |
| 17335 GL_INVALID_OPERATION, |
| 17336 "glSetSurfaceHandleCHROMIUM", |
| 17337 "Could not acquire a window for this surface handle"); |
| 17338 return; |
| 17339 } |
| 17340 |
| 17341 direct_render_state_.reset(new DirectRenderState()); |
| 17342 direct_render_state_->direct_surface = |
| 17343 new gl::NativeViewGLSurfaceEGL(window); |
| 17344 |
| 17345 // It would be useful if we could get a custom surface format such |
| 17346 // as one with a depth buffer here, but the new surface must use |
| 17347 // the same format as the one originally used for creating the GL |
| 17348 // context. Anything else just results in BAD_MATCH errors. |
| 17349 bool initialize_success = direct_render_state_->direct_surface->Initialize( |
| 17350 surface_->GetFormat()); |
| 17351 if (!initialize_success) { |
| 17352 LOG(ERROR) << "Direct render surface init failed for handle " << |
| 17353 surface_handle; |
| 17354 } |
| 17355 ANativeWindow_release(window); |
| 17356 |
| 17357 direct_render_state_->orig_surface = surface_; |
| 17358 |
| 17359 // Offscreen surfaces don't support SwapBuffers, make sure it's not |
| 17360 // considered offscreen. Various code in this file checks for is_offscreen |
| 17361 // = !!offscreen_target_frame_buffer_.get(). |
| 17362 direct_render_state_->orig_offscreen_target_frame_buffer = |
| 17363 std::move(offscreen_target_frame_buffer_); |
| 17364 offscreen_target_frame_buffer_.reset(nullptr); |
| 17365 |
| 17366 // Activate the surface and make it current. This does *not* |
| 17367 // rebind the active framebuffer, if the client is drawing to |
| 17368 // a bound FBO they will continue to do so. |
| 17369 SetSurface(direct_render_state_->direct_surface); |
| 17370 context_->MakeCurrent(surface_.get()); |
| 17371 |
| 17372 // Resize the surface to match the offscreen buffer, and update |
| 17373 // decoder feature flags to match its properties. Changing |
| 17374 // the scale is not supported, NativeViewGLSurfaceEGL::Resize |
| 17375 // ignores scale_factor and has_alpha. |
| 17376 surface_->Resize(offscreen_size_, |
| 17377 1.0f, |
| 17378 ClientExposedBackBufferHasAlpha()); |
| 17379 ApplySurfaceAttributesAndGetAlphaBits(false, attrib_helper_); |
| 17380 ApplySurfaceFeatures(); |
| 17381 |
| 17382 if (!framebuffer_state_.bound_draw_framebuffer.get()) { |
| 17383 // DoReadBuffer and DoDrawBuffersEXT may have modified bindings. |
| 17384 // We don't care for modifications to a user-bound framebuffer |
| 17385 // since those will still be valid. Target GL_NONE also remains |
| 17386 // valid, so we just need to undo the GL_BACK -> |
| 17387 // GL_COLOR_ATTACHMENT0 mapping. Caveat: the current buffer |
| 17388 // content is not preserved across this surface switch. |
| 17389 if (back_buffer_read_buffer_ == GL_BACK) { |
| 17390 glReadBuffer(GL_BACK); |
| 17391 } |
| 17392 if (back_buffer_draw_buffer_ == GL_BACK) { |
| 17393 GLenum buf = GL_BACK; |
| 17394 glDrawBuffersARB(1, &buf); |
| 17395 } |
| 17396 } |
| 17397 } else { |
| 17398 // Restore original state for drawing offscreen. |
| 17399 |
| 17400 // Redundant calls or attempts to unset a surface that wasn't set |
| 17401 // by this function are not supported. |
| 17402 if (!direct_render_state_) { |
| 17403 LOCAL_SET_GL_ERROR( |
| 17404 GL_INVALID_OPERATION, |
| 17405 "glSetSurfaceHandleCHROMIUM", |
| 17406 "Surface was not set by glSetSurfaceHandleCHROMIUM, cannot unset"); |
| 17407 } |
| 17408 |
| 17409 offscreen_target_frame_buffer_ = |
| 17410 std::move(direct_render_state_->orig_offscreen_target_frame_buffer); |
| 17411 |
| 17412 // The viewport size may have been changed, resize it based on the |
| 17413 // current surface size. Get the size while the direct surface is |
| 17414 // current, then apply the size after making the offscreen framebuffer |
| 17415 // current. |
| 17416 gfx::Size surface_size = surface_->GetSize(); |
| 17417 SetSurface(direct_render_state_->orig_surface); |
| 17418 context_->MakeCurrent(surface_.get()); |
| 17419 if (!ResizeOffscreenFramebuffer(surface_size)) { |
| 17420 LOCAL_SET_GL_ERROR( |
| 17421 GL_INVALID_OPERATION, |
| 17422 "glSetSurfaceHandleCHROMIUM", |
| 17423 "Failed to resize offscreen framebuffer"); |
| 17424 } |
| 17425 ApplySurfaceAttributesAndGetAlphaBits(true, attrib_helper_); |
| 17426 ApplySurfaceFeatures(); |
| 17427 |
| 17428 if (!framebuffer_state_.bound_draw_framebuffer.get()) { |
| 17429 // If using the default framebuffer, remap GL_BACK to |
| 17430 // GL_COLOR_ATTACHMENT0 for read and draw. |
| 17431 if (back_buffer_read_buffer_ == GL_BACK) { |
| 17432 glReadBuffer(GL_COLOR_ATTACHMENT0); |
| 17433 } |
| 17434 if (back_buffer_draw_buffer_ == GL_BACK) { |
| 17435 GLenum buf = GL_COLOR_ATTACHMENT0; |
| 17436 glDrawBuffersARB(1, &buf); |
| 17437 } |
| 17438 } |
| 17439 |
| 17440 // Trust the state struct's destructors to handle refcounting for |
| 17441 // surfaces and trigger apprpriate cleanup. |
| 17442 direct_render_state_.reset(); |
| 17443 } |
| 17444 #else // !OS_ANDROID |
| 17445 LOCAL_SET_GL_ERROR( |
| 17446 GL_INVALID_OPERATION, |
| 17447 "glSetSurfaceHandleCHROMIUM", |
| 17448 "Direct render surface is unsupported on this platform"); |
| 17449 #endif |
| 17450 } |
| 17451 |
17264 void GLES2DecoderImpl::DoInsertEventMarkerEXT( | 17452 void GLES2DecoderImpl::DoInsertEventMarkerEXT( |
17265 GLsizei length, const GLchar* marker) { | 17453 GLsizei length, const GLchar* marker) { |
17266 if (!marker) { | 17454 if (!marker) { |
17267 marker = ""; | 17455 marker = ""; |
17268 } | 17456 } |
17269 debug_marker_manager_.SetMarker( | 17457 debug_marker_manager_.SetMarker( |
17270 length ? std::string(marker, length) : std::string(marker)); | 17458 length ? std::string(marker, length) : std::string(marker)); |
17271 } | 17459 } |
17272 | 17460 |
17273 void GLES2DecoderImpl::DoPushGroupMarkerEXT( | 17461 void GLES2DecoderImpl::DoPushGroupMarkerEXT( |
(...skipping 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19118 } | 19306 } |
19119 | 19307 |
19120 // Include the auto-generated part of this file. We split this because it means | 19308 // Include the auto-generated part of this file. We split this because it means |
19121 // we can easily edit the non-auto generated parts right here in this file | 19309 // we can easily edit the non-auto generated parts right here in this file |
19122 // instead of having to edit some template or the code generator. | 19310 // instead of having to edit some template or the code generator. |
19123 #include "base/macros.h" | 19311 #include "base/macros.h" |
19124 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 19312 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
19125 | 19313 |
19126 } // namespace gles2 | 19314 } // namespace gles2 |
19127 } // namespace gpu | 19315 } // namespace gpu |
OLD | NEW |