Chromium Code Reviews| 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 |