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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2447423002: Handle CompressedTex{Sub}Image{2|3}D interaction with PBO. (Closed)
Patch Set: client side Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <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 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 855
856 GLsizei GetBoundFramebufferSamples(GLenum target); 856 GLsizei GetBoundFramebufferSamples(GLenum target);
857 857
858 // Return 0 if no depth attachment. 858 // Return 0 if no depth attachment.
859 GLenum GetBoundFramebufferDepthFormat(GLenum target); 859 GLenum GetBoundFramebufferDepthFormat(GLenum target);
860 // Return 0 if no stencil attachment. 860 // Return 0 if no stencil attachment.
861 GLenum GetBoundFramebufferStencilFormat(GLenum target); 861 GLenum GetBoundFramebufferStencilFormat(GLenum target);
862 862
863 void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i); 863 void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i);
864 864
865 // Wrapper for CompressedTexImage2D commands. 865 // Wrapper for CompressedTexImage{2|3}D commands.
866 error::Error DoCompressedTexImage2D( 866 error::Error DoCompressedTexImage(
867 GLenum target, 867 GLenum target,
868 GLint level, 868 GLint level,
869 GLenum internal_format, 869 GLenum internal_format,
870 GLsizei width,
871 GLsizei height,
872 GLint border,
873 GLsizei image_size,
874 const void* data);
875
876 // Wrapper for CompressedTexImage3D commands.
877 error::Error DoCompressedTexImage3D(
878 GLenum target,
879 GLint level,
880 GLenum internal_format,
881 GLsizei width, 870 GLsizei width,
882 GLsizei height, 871 GLsizei height,
883 GLsizei depth, 872 GLsizei depth,
884 GLint border, 873 GLint border,
885 GLsizei image_size, 874 GLsizei image_size,
886 const void* data); 875 const void* data,
876 ContextState::Dimension dimension);
887 877
888 // Wrapper for CompressedTexSubImage2D. 878 // Wrapper for CompressedTexSubImage{2|3}D.
889 void DoCompressedTexSubImage2D( 879 error::Error DoCompressedTexSubImage(
890 GLenum target, 880 GLenum target,
891 GLint level, 881 GLint level,
892 GLint xoffset, 882 GLint xoffset,
893 GLint yoffset,
894 GLsizei width,
895 GLsizei height,
896 GLenum format,
897 GLsizei imageSize,
898 const void* data);
899
900 // Wrapper for CompressedTexSubImage3D.
901 void DoCompressedTexSubImage3D(
902 GLenum target,
903 GLint level,
904 GLint xoffset,
905 GLint yoffset, 883 GLint yoffset,
906 GLint zoffset, 884 GLint zoffset,
907 GLsizei width, 885 GLsizei width,
908 GLsizei height, 886 GLsizei height,
909 GLsizei depth, 887 GLsizei depth,
910 GLenum format, 888 GLenum format,
911 GLsizei image_size, 889 GLsizei imageSize,
912 const void* data); 890 const void* data,
891 ContextState::Dimension dimension);
913 892
914 // Validate if |format| is valid for CopyTex{Sub}Image functions. 893 // Validate if |format| is valid for CopyTex{Sub}Image functions.
915 // If not, generate a GL error and return false. 894 // If not, generate a GL error and return false.
916 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, 895 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format,
917 GLenum read_format, GLenum read_type); 896 GLenum read_format, GLenum read_type);
918 897
919 // Wrapper for CopyTexImage2D. 898 // Wrapper for CopyTexImage2D.
920 void DoCopyTexImage2D( 899 void DoCopyTexImage2D(
921 GLenum target, 900 GLenum target,
922 GLint level, 901 GLint level,
(...skipping 12125 matching lines...) Expand 10 before | Expand all | Expand 10 after
13048 GLenum internal_format = static_cast<GLenum>(c.internalformat); 13027 GLenum internal_format = static_cast<GLenum>(c.internalformat);
13049 GLsizei width = static_cast<GLsizei>(c.width); 13028 GLsizei width = static_cast<GLsizei>(c.width);
13050 GLsizei height = static_cast<GLsizei>(c.height); 13029 GLsizei height = static_cast<GLsizei>(c.height);
13051 GLuint bucket_id = static_cast<GLuint>(c.bucket_id); 13030 GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
13052 GLint border = static_cast<GLint>(c.border); 13031 GLint border = static_cast<GLint>(c.border);
13053 Bucket* bucket = GetBucket(bucket_id); 13032 Bucket* bucket = GetBucket(bucket_id);
13054 if (!bucket) 13033 if (!bucket)
13055 return error::kInvalidArguments; 13034 return error::kInvalidArguments;
13056 uint32_t image_size = bucket->size(); 13035 uint32_t image_size = bucket->size();
13057 const void* data = bucket->GetData(0, image_size); 13036 const void* data = bucket->GetData(0, image_size);
13058 DCHECK(data || !image_size); 13037 DCHECK(data || !image_size);
piman 2016/10/26 21:53:22 Oh, I forgot one thing in the previous review - an
Zhenyao Mo 2016/10/26 22:31:58 Good catch. Added.
13059 return DoCompressedTexImage2D(target, level, internal_format, width, height, 13038 return DoCompressedTexImage(target, level, internal_format, width, height, 1,
13060 border, image_size, data); 13039 border, image_size, data, ContextState::k2D);
13061 } 13040 }
13062 13041
13063 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( 13042 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
13064 uint32_t immediate_data_size, const volatile void* cmd_data) { 13043 uint32_t immediate_data_size, const volatile void* cmd_data) {
13065 const volatile gles2::cmds::CompressedTexImage2D& c = 13044 const volatile gles2::cmds::CompressedTexImage2D& c =
13066 *static_cast<const volatile gles2::cmds::CompressedTexImage2D*>(cmd_data); 13045 *static_cast<const volatile gles2::cmds::CompressedTexImage2D*>(cmd_data);
13067 GLenum target = static_cast<GLenum>(c.target); 13046 GLenum target = static_cast<GLenum>(c.target);
13068 GLint level = static_cast<GLint>(c.level); 13047 GLint level = static_cast<GLint>(c.level);
13069 GLenum internal_format = static_cast<GLenum>(c.internalformat); 13048 GLenum internal_format = static_cast<GLenum>(c.internalformat);
13070 GLsizei width = static_cast<GLsizei>(c.width); 13049 GLsizei width = static_cast<GLsizei>(c.width);
13071 GLsizei height = static_cast<GLsizei>(c.height); 13050 GLsizei height = static_cast<GLsizei>(c.height);
13072 GLint border = static_cast<GLint>(c.border); 13051 GLint border = static_cast<GLint>(c.border);
13073 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 13052 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
13074 uint32_t data_size = image_size;
13075 uint32_t data_shm_id = c.data_shm_id; 13053 uint32_t data_shm_id = c.data_shm_id;
13076 uint32_t data_shm_offset = c.data_shm_offset; 13054 uint32_t data_shm_offset = c.data_shm_offset;
13077 13055
13078 const void* data; 13056 const void* data;
13079 if (state_.bound_pixel_unpack_buffer.get()) { 13057 if (state_.bound_pixel_unpack_buffer.get()) {
13080 if (data_shm_id) { 13058 if (data_shm_id) {
13081 return error::kInvalidArguments; 13059 return error::kInvalidArguments;
13082 } 13060 }
13083 data = reinterpret_cast<const void*>(data_shm_offset); 13061 data = reinterpret_cast<const void*>(data_shm_offset);
13084 } else { 13062 } else {
13085 if (!data_shm_id && data_shm_offset) { 13063 if (!data_shm_id && data_shm_offset) {
13086 return error::kInvalidArguments; 13064 return error::kInvalidArguments;
13087 } 13065 }
13088 data = GetSharedMemoryAs<const void*>( 13066 data = GetSharedMemoryAs<const void*>(
13089 data_shm_id, data_shm_offset, data_size); 13067 data_shm_id, data_shm_offset, image_size);
13090 } 13068 }
13091 return DoCompressedTexImage2D(target, level, internal_format, width, height, 13069 return DoCompressedTexImage(target, level, internal_format, width, height, 1,
13092 border, image_size, data); 13070 border, image_size, data, ContextState::k2D);
13093 } 13071 }
13094 13072
13095 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( 13073 error::Error GLES2DecoderImpl::HandleCompressedTexImage3DBucket(
13074 uint32_t immediate_data_size, const volatile void* cmd_data) {
13075 if (!unsafe_es3_apis_enabled())
13076 return error::kUnknownCommand;
13077 const volatile gles2::cmds::CompressedTexImage3DBucket& c =
13078 *static_cast<const volatile gles2::cmds::CompressedTexImage3DBucket*>(
13079 cmd_data);
13080 GLenum target = static_cast<GLenum>(c.target);
13081 GLint level = static_cast<GLint>(c.level);
13082 GLenum internal_format = static_cast<GLenum>(c.internalformat);
13083 GLsizei width = static_cast<GLsizei>(c.width);
13084 GLsizei height = static_cast<GLsizei>(c.height);
13085 GLsizei depth = static_cast<GLsizei>(c.depth);
13086 GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
13087 GLint border = static_cast<GLint>(c.border);
13088 Bucket* bucket = GetBucket(bucket_id);
13089 if (!bucket)
13090 return error::kInvalidArguments;
13091 uint32_t image_size = bucket->size();
13092 const void* data = bucket->GetData(0, image_size);
13093 DCHECK(data || !image_size);
13094 return DoCompressedTexImage(target, level, internal_format, width, height,
13095 depth, border, image_size, data,
13096 ContextState::k3D);
13097 }
13098
13099 error::Error GLES2DecoderImpl::HandleCompressedTexImage3D(
13100 uint32_t immediate_data_size, const volatile void* cmd_data) {
13101 if (!unsafe_es3_apis_enabled())
13102 return error::kUnknownCommand;
13103 const volatile gles2::cmds::CompressedTexImage3D& c =
13104 *static_cast<const volatile gles2::cmds::CompressedTexImage3D*>(cmd_data);
13105 GLenum target = static_cast<GLenum>(c.target);
13106 GLint level = static_cast<GLint>(c.level);
13107 GLenum internal_format = static_cast<GLenum>(c.internalformat);
13108 GLsizei width = static_cast<GLsizei>(c.width);
13109 GLsizei height = static_cast<GLsizei>(c.height);
13110 GLsizei depth = static_cast<GLsizei>(c.depth);
13111 GLint border = static_cast<GLint>(c.border);
13112 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
13113 uint32_t data_shm_id = c.data_shm_id;
13114 uint32_t data_shm_offset = c.data_shm_offset;
13115
13116 const void* data;
13117 if (state_.bound_pixel_unpack_buffer.get()) {
13118 if (data_shm_id) {
13119 return error::kInvalidArguments;
13120 }
13121 data = reinterpret_cast<const void*>(data_shm_offset);
13122 } else {
13123 if (!data_shm_id && data_shm_offset) {
13124 return error::kInvalidArguments;
13125 }
13126 data = GetSharedMemoryAs<const void*>(
13127 data_shm_id, data_shm_offset, image_size);
13128 }
13129 return DoCompressedTexImage(target, level, internal_format, width, height,
13130 depth, border, image_size, data,
13131 ContextState::k3D);
13132 }
13133
13134 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3DBucket(
13135 uint32_t immediate_data_size, const volatile void* cmd_data) {
13136 if (!unsafe_es3_apis_enabled())
13137 return error::kUnknownCommand;
13138 const volatile gles2::cmds::CompressedTexSubImage3DBucket& c =
13139 *static_cast<const volatile gles2::cmds::CompressedTexSubImage3DBucket*>(
13140 cmd_data);
13141 GLenum target = static_cast<GLenum>(c.target);
13142 GLint level = static_cast<GLint>(c.level);
13143 GLint xoffset = static_cast<GLint>(c.xoffset);
13144 GLint yoffset = static_cast<GLint>(c.yoffset);
13145 GLint zoffset = static_cast<GLint>(c.zoffset);
13146 GLsizei width = static_cast<GLsizei>(c.width);
13147 GLsizei height = static_cast<GLsizei>(c.height);
13148 GLsizei depth = static_cast<GLsizei>(c.depth);
13149 GLenum format = static_cast<GLenum>(c.format);
13150 GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
13151 Bucket* bucket = GetBucket(bucket_id);
13152 if (!bucket)
13153 return error::kInvalidArguments;
13154 uint32_t image_size = bucket->size();
13155 const void* data = bucket->GetData(0, image_size);
13156 DCHECK(data || !image_size);
13157 return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset,
13158 width, height, depth, format, image_size,
13159 data, ContextState::k3D);
13160 }
13161
13162 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3D(
13163 uint32_t immediate_data_size, const volatile void* cmd_data) {
13164 if (!unsafe_es3_apis_enabled())
13165 return error::kUnknownCommand;
13166 const volatile gles2::cmds::CompressedTexSubImage3D& c =
13167 *static_cast<const volatile gles2::cmds::CompressedTexSubImage3D*>(
13168 cmd_data);
13169 GLenum target = static_cast<GLenum>(c.target);
13170 GLint level = static_cast<GLint>(c.level);
13171 GLint xoffset = static_cast<GLint>(c.xoffset);
13172 GLint yoffset = static_cast<GLint>(c.yoffset);
13173 GLint zoffset = static_cast<GLint>(c.zoffset);
13174 GLsizei width = static_cast<GLsizei>(c.width);
13175 GLsizei height = static_cast<GLsizei>(c.height);
13176 GLsizei depth = static_cast<GLsizei>(c.depth);
13177 GLenum format = static_cast<GLenum>(c.format);
13178 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
13179 uint32_t data_shm_id = c.data_shm_id;
13180 uint32_t data_shm_offset = c.data_shm_offset;
13181
13182 const void* data;
13183 if (state_.bound_pixel_unpack_buffer.get()) {
13184 if (data_shm_id) {
13185 return error::kInvalidArguments;
13186 }
13187 data = reinterpret_cast<const void*>(data_shm_offset);
13188 } else {
13189 if (!data_shm_id && data_shm_offset) {
13190 return error::kInvalidArguments;
13191 }
13192 data = GetSharedMemoryAs<const void*>(
13193 data_shm_id, data_shm_offset, image_size);
13194 }
13195 return DoCompressedTexSubImage(target, level, xoffset, yoffset, zoffset,
13196 width, height, depth, format, image_size,
13197 data, ContextState::k3D);
13198 }
13199
13200 error::Error GLES2DecoderImpl::DoCompressedTexImage(
13096 GLenum target, GLint level, GLenum internal_format, GLsizei width, 13201 GLenum target, GLint level, GLenum internal_format, GLsizei width,
13097 GLsizei height, GLint border, GLsizei image_size, const void* data) { 13202 GLsizei height, GLsizei depth, GLint border, GLsizei image_size,
13098 const char* func_name = "glCompressedTexImage2D"; 13203 const void* data, ContextState::Dimension dimension) {
13099 if (!validators_->texture_target.IsValid(target)) { 13204 const char* func_name;
13100 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); 13205 if (dimension == ContextState::k2D) {
13101 return error::kNoError; 13206 func_name = "glCompressedTexImage2D";
13102 } 13207 if (!validators_->texture_target.IsValid(target)) {
13103 // TODO(ccameron): Add a separate texture from |texture_target| for 13208 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
13104 // [Compressed]Tex[Sub]Image2D and related functions. 13209 return error::kNoError;
13105 // http://crbug.com/536854 13210 }
13106 if (target == GL_TEXTURE_RECTANGLE_ARB) { 13211 // TODO(ccameron): Add a separate texture from |texture_target| for
13107 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); 13212 // [Compressed]Tex[Sub]Image2D and related functions.
13108 return error::kNoError; 13213 // http://crbug.com/536854
13214 if (target == GL_TEXTURE_RECTANGLE_ARB) {
13215 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
13216 return error::kNoError;
13217 }
13218 } else {
13219 DCHECK_EQ(ContextState::k3D, dimension);
13220 func_name = "glCompressedTexImage3D";
13221 if (!validators_->texture_3_d_target.IsValid(target)) {
13222 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
13223 return error::kNoError;
13224 }
13109 } 13225 }
13110 if (!validators_->compressed_texture_format.IsValid(internal_format)) { 13226 if (!validators_->compressed_texture_format.IsValid(internal_format)) {
13111 LOCAL_SET_GL_ERROR_INVALID_ENUM( 13227 LOCAL_SET_GL_ERROR_INVALID_ENUM(
13112 func_name, internal_format, "internalformat"); 13228 func_name, internal_format, "internalformat");
13113 return error::kNoError; 13229 return error::kNoError;
13114 } 13230 }
13115 if (image_size < 0) { 13231 if (image_size < 0) {
13116 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0"); 13232 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
13117 return error::kNoError; 13233 return error::kNoError;
13118 } 13234 }
13119 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 13235 if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
13120 border != 0) { 13236 border != 0) {
13121 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range"); 13237 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
13122 return error::kNoError; 13238 return error::kNoError;
13123 } 13239 }
13124 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 13240 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13125 &state_, target); 13241 &state_, target);
13126 if (!texture_ref) { 13242 if (!texture_ref) {
13127 LOCAL_SET_GL_ERROR( 13243 LOCAL_SET_GL_ERROR(
13128 GL_INVALID_VALUE, func_name, "no texture bound at target"); 13244 GL_INVALID_VALUE, func_name, "no texture bound at target");
13129 return error::kNoError; 13245 return error::kNoError;
13130 } 13246 }
13131 Texture* texture = texture_ref->texture(); 13247 Texture* texture = texture_ref->texture();
13132 if (texture->IsImmutable()) { 13248 if (texture->IsImmutable()) {
13133 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable"); 13249 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable");
13134 return error::kNoError; 13250 return error::kNoError;
13135 } 13251 }
13252
13136 if (!ValidateCompressedTexDimensions(func_name, target, level, 13253 if (!ValidateCompressedTexDimensions(func_name, target, level,
13137 width, height, 1, internal_format) || 13254 width, height, depth, internal_format) ||
13138 !ValidateCompressedTexFuncData(func_name, width, height, 1, 13255 !ValidateCompressedTexFuncData(func_name, width, height, depth,
13139 internal_format, image_size, data)) { 13256 internal_format, image_size, data)) {
13140 return error::kNoError; 13257 return error::kNoError;
13141 } 13258 }
13142 13259
13143 if (!EnsureGPUMemoryAvailable(image_size)) { 13260 if (!EnsureGPUMemoryAvailable(image_size)) {
13144 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "out of memory"); 13261 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "out of memory");
13145 return error::kNoError; 13262 return error::kNoError;
13146 } 13263 }
13147 13264
13148 if (texture->IsAttachedToFramebuffer()) { 13265 if (texture->IsAttachedToFramebuffer()) {
13149 framebuffer_state_.clear_state_dirty = true; 13266 framebuffer_state_.clear_state_dirty = true;
13150 } 13267 }
13151 13268
13152 std::unique_ptr<int8_t[]> zero; 13269 std::unique_ptr<int8_t[]> zero;
13153 if (!state_.bound_pixel_unpack_buffer && !data) { 13270 if (!state_.bound_pixel_unpack_buffer && !data) {
13154 zero.reset(new int8_t[image_size]); 13271 zero.reset(new int8_t[image_size]);
13155 memset(zero.get(), 0, image_size); 13272 memset(zero.get(), 0, image_size);
13156 data = zero.get(); 13273 data = zero.get();
13157 } 13274 }
13158 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name); 13275 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
13159
13160 const CompressedFormatInfo* format_info = 13276 const CompressedFormatInfo* format_info =
13161 GetCompressedFormatInfo(internal_format); 13277 GetCompressedFormatInfo(internal_format);
13162 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { 13278 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
13163 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
13164 state_, *format_info, width, height, 1, image_size, data);
13165 if (!decompressed_data) {
13166 MarkContextLost(error::kGuilty);
13167 group_->LoseContexts(error::kInnocent);
13168 return error::kLostContext;
13169 }
13170 state_.PushTextureDecompressionUnpackState();
13171 glTexImage2D(target, level, format_info->decompressed_internal_format,
13172 width, height, border, format_info->decompressed_format,
13173 format_info->decompressed_type, decompressed_data.get());
13174 state_.RestoreUnpackState();
13175 } else {
13176 glCompressedTexImage2D(target, level, internal_format, width, height,
13177 border, image_size, data);
13178 }
13179 GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
13180 if (error == GL_NO_ERROR) {
13181 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
13182 width, height, 1, border, 0, 0,
13183 gfx::Rect(width, height));
13184 }
13185
13186 // This may be a slow command. Exit command processing to allow for
13187 // context preemption and GPU watchdog checks.
13188 ExitCommandProcessingEarly();
13189 return error::kNoError;
13190 }
13191
13192 error::Error GLES2DecoderImpl::DoCompressedTexImage3D(
13193 GLenum target,
13194 GLint level,
13195 GLenum internal_format,
13196 GLsizei width,
13197 GLsizei height,
13198 GLsizei depth,
13199 GLint border,
13200 GLsizei image_size,
13201 const void* data) {
13202 if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
13203 border != 0) {
13204 LOCAL_SET_GL_ERROR(
13205 GL_INVALID_VALUE,
13206 "glCompressedTexImage3D", "dimensions out of range");
13207 return error::kNoError;
13208 }
13209 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13210 &state_, target);
13211 if (!texture_ref) {
13212 LOCAL_SET_GL_ERROR(
13213 GL_INVALID_VALUE,
13214 "glCompressedTexImage3D", "unknown texture target");
13215 return error::kNoError;
13216 }
13217 Texture* texture = texture_ref->texture();
13218 if (texture->IsImmutable()) {
13219 LOCAL_SET_GL_ERROR(
13220 GL_INVALID_OPERATION,
13221 "glCompressedTexImage3D", "texture is immutable");
13222 return error::kNoError;
13223 }
13224
13225 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level,
13226 width, height, depth, internal_format) ||
13227 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height,
13228 depth, internal_format, image_size,
13229 data)) {
13230 return error::kNoError;
13231 }
13232
13233 if (!EnsureGPUMemoryAvailable(image_size)) {
13234 LOCAL_SET_GL_ERROR(
13235 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory");
13236 return error::kNoError;
13237 }
13238
13239 if (texture->IsAttachedToFramebuffer()) {
13240 framebuffer_state_.clear_state_dirty = true;
13241 }
13242
13243 std::unique_ptr<int8_t[]> zero;
13244 if (!state_.bound_pixel_unpack_buffer && !data) {
13245 zero.reset(new int8_t[image_size]);
13246 memset(zero.get(), 0, image_size);
13247 data = zero.get();
13248 }
13249 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D");
13250 const CompressedFormatInfo* format_info =
13251 GetCompressedFormatInfo(internal_format);
13252 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
13253 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( 13279 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
13254 state_, *format_info, width, height, depth, image_size, data); 13280 state_, *format_info, width, height, depth, image_size, data);
13255 if (!decompressed_data) { 13281 if (!decompressed_data) {
13256 MarkContextLost(error::kGuilty); 13282 MarkContextLost(error::kGuilty);
13257 group_->LoseContexts(error::kInnocent); 13283 group_->LoseContexts(error::kInnocent);
13258 return error::kLostContext; 13284 return error::kLostContext;
13259 } 13285 }
13260 state_.PushTextureDecompressionUnpackState(); 13286 state_.PushTextureDecompressionUnpackState();
13261 glTexImage3D(target, level, format_info->decompressed_internal_format, 13287 if (dimension == ContextState::k2D) {
13262 width, height, depth, border, format_info->decompressed_format, 13288 glTexImage2D(target, level, format_info->decompressed_internal_format,
13263 format_info->decompressed_type, decompressed_data.get()); 13289 width, height, border, format_info->decompressed_format,
13290 format_info->decompressed_type, decompressed_data.get());
13291 } else {
13292 glTexImage3D(
13293 target, level, format_info->decompressed_internal_format,
13294 width, height, depth, border, format_info->decompressed_format,
13295 format_info->decompressed_type, decompressed_data.get());
13296 }
13264 state_.RestoreUnpackState(); 13297 state_.RestoreUnpackState();
13265 } else { 13298 } else {
13266 glCompressedTexImage3D(target, level, internal_format, width, height, depth, 13299 if (dimension == ContextState::k2D) {
13267 border, image_size, data); 13300 glCompressedTexImage2D(target, level, internal_format, width, height,
13301 border, image_size, data);
13302 } else {
13303 glCompressedTexImage3D(target, level, internal_format, width, height,
13304 depth, border, image_size, data);
13305 }
13268 } 13306 }
13269 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); 13307 GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
13270 if (error == GL_NO_ERROR) { 13308 if (error == GL_NO_ERROR) {
13271 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, 13309 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
13272 width, height, depth, border, 0, 0, 13310 width, height, depth, border, 0, 0,
13273 gfx::Rect(width, height)); 13311 gfx::Rect(width, height));
13274 } 13312 }
13275 13313
13276 // This may be a slow command. Exit command processing to allow for 13314 // This may be a slow command. Exit command processing to allow for
13277 // context preemption and GPU watchdog checks. 13315 // context preemption and GPU watchdog checks.
13278 ExitCommandProcessingEarly(); 13316 ExitCommandProcessingEarly();
13279 return error::kNoError; 13317 return error::kNoError;
13280 } 13318 }
13281 13319
13282 void GLES2DecoderImpl::DoCompressedTexSubImage3D(
13283 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
13284 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
13285 GLsizei image_size, const void* data) {
13286 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
13287 LOCAL_SET_GL_ERROR(
13288 GL_INVALID_VALUE,
13289 "glCompressedTexSubImage3D", "dimensions out of range");
13290 return;
13291 }
13292 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13293 &state_, target);
13294 if (!texture_ref) {
13295 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
13296 "unknown texture for target");
13297 return;
13298 }
13299 Texture* texture = texture_ref->texture();
13300 GLenum type = 0, internal_format = 0;
13301 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
13302 std::string msg = base::StringPrintf(
13303 "level %d does not exist", level);
13304 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
13305 msg.c_str());
13306 return;
13307 }
13308 if (internal_format != format) {
13309 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
13310 "format does not match internal format");
13311 return;
13312 }
13313 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset,
13314 width, height, depth)) {
13315 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D",
13316 "bad dimensions");
13317 return;
13318 }
13319 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", width, height,
13320 depth, format, image_size, data) ||
13321 !ValidateCompressedTexSubDimensions(
13322 "glCompressedTexSubImage3D", target, level, xoffset, yoffset, zoffset,
13323 width, height, depth, format, texture)) {
13324 return;
13325 }
13326
13327 // Note: There is no need to deal with texture cleared tracking here
13328 // because the validation above means you can only get here if the level
13329 // is already a matching compressed format and in that case
13330 // CompressedTexImage3D already cleared the texture.
13331
13332 const CompressedFormatInfo* format_info =
13333 GetCompressedFormatInfo(internal_format);
13334 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
13335 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
13336 state_, *format_info, width, height, depth, image_size, data);
13337 if (!decompressed_data) {
13338 MarkContextLost(error::kGuilty);
13339 group_->LoseContexts(error::kInnocent);
13340 return;
13341 }
13342 state_.PushTextureDecompressionUnpackState();
13343 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
13344 depth, format_info->decompressed_format,
13345 format_info->decompressed_type, decompressed_data.get());
13346 state_.RestoreUnpackState();
13347 } else {
13348 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
13349 height, depth, format, image_size, data);
13350 }
13351
13352 // This may be a slow command. Exit command processing to allow for
13353 // context preemption and GPU watchdog checks.
13354 ExitCommandProcessingEarly();
13355 }
13356
13357 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, 13320 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size,
13358 const volatile void* cmd_data) { 13321 const volatile void* cmd_data) {
13359 const char* func_name = "glTexImage2D"; 13322 const char* func_name = "glTexImage2D";
13360 const volatile gles2::cmds::TexImage2D& c = 13323 const volatile gles2::cmds::TexImage2D& c =
13361 *static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data); 13324 *static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data);
13362 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", 13325 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
13363 "width", c.width, "height", c.height); 13326 "width", c.width, "height", c.height);
13364 // Set as failed for now, but if it successed, this will be set to not failed. 13327 // Set as failed for now, but if it successed, this will be set to not failed.
13365 texture_state_.tex_image_failed = true; 13328 texture_state_.tex_image_failed = true;
13366 GLenum target = static_cast<GLenum>(c.target); 13329 GLenum target = static_cast<GLenum>(c.target);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
13533 TextureManager::DoTexImageArguments::kTexImage3D }; 13496 TextureManager::DoTexImageArguments::kTexImage3D };
13534 texture_manager()->ValidateAndDoTexImage( 13497 texture_manager()->ValidateAndDoTexImage(
13535 &texture_state_, &state_, &framebuffer_state_, func_name, args); 13498 &texture_state_, &state_, &framebuffer_state_, func_name, args);
13536 13499
13537 // This may be a slow command. Exit command processing to allow for 13500 // This may be a slow command. Exit command processing to allow for
13538 // context preemption and GPU watchdog checks. 13501 // context preemption and GPU watchdog checks.
13539 ExitCommandProcessingEarly(); 13502 ExitCommandProcessingEarly();
13540 return error::kNoError; 13503 return error::kNoError;
13541 } 13504 }
13542 13505
13543 void GLES2DecoderImpl::DoCompressedTexSubImage2D( 13506 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
13544 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 13507 uint32_t immediate_data_size, const volatile void* cmd_data) {
13545 GLsizei height, GLenum format, GLsizei image_size, const void * data) { 13508 const volatile gles2::cmds::CompressedTexSubImage2DBucket& c =
13509 *static_cast<const volatile gles2::cmds::CompressedTexSubImage2DBucket*>(
13510 cmd_data);
13511 GLenum target = static_cast<GLenum>(c.target);
13512 GLint level = static_cast<GLint>(c.level);
13513 GLint xoffset = static_cast<GLint>(c.xoffset);
13514 GLint yoffset = static_cast<GLint>(c.yoffset);
13515 GLsizei width = static_cast<GLsizei>(c.width);
13516 GLsizei height = static_cast<GLsizei>(c.height);
13517 GLenum format = static_cast<GLenum>(c.format);
13518 GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
13519 Bucket* bucket = GetBucket(bucket_id);
13520 if (!bucket)
13521 return error::kInvalidArguments;
13522 uint32_t image_size = bucket->size();
13523 const void* data = bucket->GetData(0, image_size);
13524 DCHECK(data || !image_size);
13525 return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0,
13526 width, height, 1, format, image_size, data,
13527 ContextState::k2D);
13528 }
13529
13530 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
13531 uint32_t immediate_data_size,
13532 const volatile void* cmd_data) {
13533 const volatile gles2::cmds::CompressedTexSubImage2D& c =
13534 *static_cast<const volatile gles2::cmds::CompressedTexSubImage2D*>(
13535 cmd_data);
13536 GLenum target = static_cast<GLenum>(c.target);
13537 GLint level = static_cast<GLint>(c.level);
13538 GLint xoffset = static_cast<GLint>(c.xoffset);
13539 GLint yoffset = static_cast<GLint>(c.yoffset);
13540 GLsizei width = static_cast<GLsizei>(c.width);
13541 GLsizei height = static_cast<GLsizei>(c.height);
13542 GLenum format = static_cast<GLenum>(c.format);
13543 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
13544 uint32_t data_shm_id = c.data_shm_id;
13545 uint32_t data_shm_offset = c.data_shm_offset;
13546
13547 const void* data;
13548 if (state_.bound_pixel_unpack_buffer.get()) {
13549 if (data_shm_id) {
13550 return error::kInvalidArguments;
13551 }
13552 data = reinterpret_cast<const void*>(data_shm_offset);
13553 } else {
13554 if (!data_shm_id && data_shm_offset) {
13555 return error::kInvalidArguments;
13556 }
13557 data = GetSharedMemoryAs<const void*>(
13558 data_shm_id, data_shm_offset, image_size);
13559 }
13560 return DoCompressedTexSubImage(target, level, xoffset, yoffset, 0,
13561 width, height, 1, format, image_size, data,
13562 ContextState::k2D);
13563 }
13564
13565 error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
13566 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
13567 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
13568 GLsizei image_size, const void * data, ContextState::Dimension dimension) {
13569 const char* func_name;
13570 if (dimension == ContextState::k2D) {
13571 func_name = "glCompressedTexSubImage2D";
13572 if (!validators_->texture_target.IsValid(target)) {
13573 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
13574 return error::kNoError;
13575 }
13576 } else {
13577 DCHECK_EQ(ContextState::k3D, dimension);
13578 func_name = "glCompressedTexSubImage3D";
13579 if (!validators_->texture_3_d_target.IsValid(target)) {
13580 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
13581 return error::kNoError;
13582 }
13583 }
13584 if (!validators_->compressed_texture_format.IsValid(format)) {
13585 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format");
13586 return error::kNoError;
13587 }
13588 if (image_size < 0) {
13589 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
13590 return error::kNoError;
13591 }
13592 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
13593 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
13594 return error::kNoError;
13595 }
13546 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 13596 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13547 &state_, target); 13597 &state_, target);
13548 if (!texture_ref) { 13598 if (!texture_ref) {
13549 LOCAL_SET_GL_ERROR( 13599 LOCAL_SET_GL_ERROR(
13550 GL_INVALID_OPERATION, 13600 GL_INVALID_OPERATION, func_name, "no texture bound at target");
13551 "glCompressedTexSubImage2D", "unknown texture for target"); 13601 return error::kNoError;
13552 return;
13553 }
13554 if (!texture_manager()->ValidForTarget(target, level, width, height, 1)) {
13555 LOCAL_SET_GL_ERROR(
13556 GL_INVALID_VALUE,
13557 "glCompressedTexSubImage2D", "dimensions out of range");
13558 return;
13559 } 13602 }
13560 Texture* texture = texture_ref->texture(); 13603 Texture* texture = texture_ref->texture();
13561 GLenum type = 0; 13604 GLenum type = 0;
13562 GLenum internal_format = 0; 13605 GLenum internal_format = 0;
13563 if (!texture->GetLevelType(target, level, &type, &internal_format)) { 13606 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
13564 std::string msg = base::StringPrintf( 13607 std::string msg = base::StringPrintf("level %d does not exist", level);
13565 "level %d does not exist", level); 13608 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, msg.c_str());
13566 LOCAL_SET_GL_ERROR( 13609 return error::kNoError;
13567 GL_INVALID_OPERATION, "glCompressedTexSubImage2D", msg.c_str());
13568 return;
13569 } 13610 }
13570 if (internal_format != format) { 13611 if (internal_format != format) {
13571 LOCAL_SET_GL_ERROR( 13612 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
13572 GL_INVALID_OPERATION, 13613 "format does not match internalformat.");
13573 "glCompressedTexSubImage2D", "format does not match internal format."); 13614 return error::kNoError;
13574 return;
13575 } 13615 }
13576 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, 13616 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset,
13577 height, 1)) { 13617 width, height, depth)) {
13578 LOCAL_SET_GL_ERROR( 13618 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "bad dimensions.");
13579 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); 13619 return error::kNoError;
13580 return;
13581 } 13620 }
13582 13621
13583 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", width, height, 13622 if (!ValidateCompressedTexFuncData(
13584 1, format, image_size, data) || 13623 func_name, width, height, depth, format, image_size, data) ||
13585 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", target, 13624 !ValidateCompressedTexSubDimensions(
13586 level, xoffset, yoffset, 0, width, 13625 func_name, target, level, xoffset, yoffset, zoffset,
13587 height, 1, format, texture)) { 13626 width, height, depth, format, texture)) {
13588 return; 13627 return error::kNoError;
13589 } 13628 }
13590 13629
13591 if (!texture->IsLevelCleared(target, level)) { 13630 // Note: There is no need to deal with texture cleared tracking here
13592 // This can only happen if the compressed texture was allocated 13631 // because the validation above means you can only get here if the level
13593 // using TexStorage2D. 13632 // is already a matching compressed format and in that case
13594 DCHECK(texture->IsImmutable()); 13633 // CompressedTexImage{2|3}D already cleared the texture.
13595 GLsizei level_width = 0, level_height = 0; 13634 DCHECK(texture->IsLevelCleared(target, level));
13596 bool success = texture->GetLevelSize(
13597 target, level, &level_width, &level_height, nullptr);
13598 DCHECK(success);
13599 // We can skip the clear if we're uploading the entire level.
13600 if (xoffset == 0 && yoffset == 0 &&
13601 width == level_width && height == level_height) {
13602 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
13603 } else {
13604 texture_manager()->ClearTextureLevel(this, texture_ref, target, level);
13605 }
13606 DCHECK(texture->IsLevelCleared(target, level));
13607 }
13608 13635
13609 const CompressedFormatInfo* format_info = 13636 const CompressedFormatInfo* format_info =
13610 GetCompressedFormatInfo(internal_format); 13637 GetCompressedFormatInfo(internal_format);
13611 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { 13638 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
13612 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( 13639 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
13613 state_, *format_info, width, height, 1, image_size, data); 13640 state_, *format_info, width, height, depth, image_size, data);
13614 if (!decompressed_data) { 13641 if (!decompressed_data) {
13615 MarkContextLost(error::kGuilty); 13642 MarkContextLost(error::kGuilty);
13616 group_->LoseContexts(error::kInnocent); 13643 group_->LoseContexts(error::kInnocent);
13617 return; 13644 return error::kLostContext;
13618 } 13645 }
13619 state_.PushTextureDecompressionUnpackState(); 13646 state_.PushTextureDecompressionUnpackState();
13620 glTexSubImage2D(target, level, xoffset, yoffset, width, height, 13647 if (dimension == ContextState::k2D) {
13621 format_info->decompressed_format, 13648 glTexSubImage2D(target, level, xoffset, yoffset, width, height,
13622 format_info->decompressed_type, decompressed_data.get()); 13649 format_info->decompressed_format,
13650 format_info->decompressed_type, decompressed_data.get());
13651 } else {
13652 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
13653 depth, format_info->decompressed_format,
13654 format_info->decompressed_type, decompressed_data.get());
13655 }
13623 state_.RestoreUnpackState(); 13656 state_.RestoreUnpackState();
13624 } else { 13657 } else {
13625 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, 13658 if (dimension == ContextState::k2D) {
13626 format, image_size, data); 13659 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height,
13660 format, image_size, data);
13661 } else {
13662 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
13663 height, depth, format, image_size, data);
13664 }
13627 } 13665 }
13628 13666
13629 // This may be a slow command. Exit command processing to allow for 13667 // This may be a slow command. Exit command processing to allow for
13630 // context preemption and GPU watchdog checks. 13668 // context preemption and GPU watchdog checks.
13631 ExitCommandProcessingEarly(); 13669 ExitCommandProcessingEarly();
13670 return error::kNoError;
13632 } 13671 }
13633 13672
13634 bool GLES2DecoderImpl::ValidateCopyTexFormat( 13673 bool GLES2DecoderImpl::ValidateCopyTexFormat(
13635 const char* func_name, GLenum internal_format, 13674 const char* func_name, GLenum internal_format,
13636 GLenum read_format, GLenum read_type) { 13675 GLenum read_format, GLenum read_type) {
13637 if (read_format == 0) { 13676 if (read_format == 0) {
13638 LOCAL_SET_GL_ERROR( 13677 LOCAL_SET_GL_ERROR(
13639 GL_INVALID_OPERATION, func_name, "no valid color image"); 13678 GL_INVALID_OPERATION, func_name, "no valid color image");
13640 return false; 13679 return false;
13641 } 13680 }
(...skipping 5063 matching lines...) Expand 10 before | Expand all | Expand 10 after
18705 } 18744 }
18706 18745
18707 // Include the auto-generated part of this file. We split this because it means 18746 // Include the auto-generated part of this file. We split this because it means
18708 // we can easily edit the non-auto generated parts right here in this file 18747 // we can easily edit the non-auto generated parts right here in this file
18709 // instead of having to edit some template or the code generator. 18748 // instead of having to edit some template or the code generator.
18710 #include "base/macros.h" 18749 #include "base/macros.h"
18711 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 18750 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
18712 18751
18713 } // namespace gles2 18752 } // namespace gles2
18714 } // namespace gpu 18753 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698