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

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

Issue 8341128: Defer clearing textures and renderbuffers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix one more unit test Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <stdio.h> 7 #include <stdio.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <list> 10 #include <list>
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // Create a new frame buffer. 346 // Create a new frame buffer.
347 void Create(); 347 void Create();
348 348
349 // Attach a color render buffer to a frame buffer. 349 // Attach a color render buffer to a frame buffer.
350 void AttachRenderTexture(Texture* texture); 350 void AttachRenderTexture(Texture* texture);
351 351
352 // Attach a render buffer to a frame buffer. Note that this unbinds any 352 // Attach a render buffer to a frame buffer. Note that this unbinds any
353 // currently bound frame buffer. 353 // currently bound frame buffer.
354 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer); 354 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer);
355 355
356 // Clear the given attached buffers.
357 void Clear(GLbitfield buffers);
358
359 // Destroy the frame buffer. This must be explicitly called before destroying 356 // Destroy the frame buffer. This must be explicitly called before destroying
360 // this object. 357 // this object.
361 void Destroy(); 358 void Destroy();
362 359
363 // Invalidate the frame buffer. This can be used when a context is lost and it 360 // Invalidate the frame buffer. This can be used when a context is lost and it
364 // is not possible to make it current in order to free the resource. 361 // is not possible to make it current in order to free the resource.
365 void Invalidate(); 362 void Invalidate();
366 363
367 // See glCheckFramebufferStatusEXT. 364 // See glCheckFramebufferStatusEXT.
368 GLenum CheckStatus(); 365 GLenum CheckStatus();
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 virtual bool SetParent(GLES2Decoder* parent_decoder, 502 virtual bool SetParent(GLES2Decoder* parent_decoder,
506 uint32 parent_texture_id); 503 uint32 parent_texture_id);
507 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size); 504 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size);
508 void UpdateParentTextureInfo(); 505 void UpdateParentTextureInfo();
509 virtual bool MakeCurrent(); 506 virtual bool MakeCurrent();
510 virtual GLES2Util* GetGLES2Util() { return &util_; } 507 virtual GLES2Util* GetGLES2Util() { return &util_; }
511 virtual gfx::GLContext* GetGLContext() { return context_.get(); } 508 virtual gfx::GLContext* GetGLContext() { return context_.get(); }
512 virtual gfx::GLSurface* GetGLSurface() { return surface_.get(); } 509 virtual gfx::GLSurface* GetGLSurface() { return surface_.get(); }
513 virtual ContextGroup* GetContextGroup() { return group_.get(); } 510 virtual ContextGroup* GetContextGroup() { return group_.get(); }
514 511
512 virtual void SetGLError(GLenum error, const char* msg);
515 virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback); 513 virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback);
516 514
517 #if defined(OS_MACOSX) 515 #if defined(OS_MACOSX)
518 virtual void SetSwapBuffersCallback(Callback0::Type* callback); 516 virtual void SetSwapBuffersCallback(Callback0::Type* callback);
519 #endif 517 #endif
520 518
521 virtual void SetStreamTextureManager(StreamTextureManager* manager); 519 virtual void SetStreamTextureManager(StreamTextureManager* manager);
522 virtual bool GetServiceTextureId(uint32 client_texture_id, 520 virtual bool GetServiceTextureId(uint32 client_texture_id,
523 uint32* service_texture_id); 521 uint32* service_texture_id);
524 522
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 const std::string& name_str); 835 const std::string& name_str);
838 836
839 error::Error GetUniformLocationHelper( 837 error::Error GetUniformLocationHelper(
840 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 838 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
841 const std::string& name_str); 839 const std::string& name_str);
842 840
843 // Helper for glShaderSource. 841 // Helper for glShaderSource.
844 error::Error ShaderSourceHelper( 842 error::Error ShaderSourceHelper(
845 GLuint client_id, const char* data, uint32 data_size); 843 GLuint client_id, const char* data, uint32 data_size);
846 844
847 // Clears any uncleared render buffers attached to the given frame buffer. 845 // Clear any textures used by the current program.
848 void ClearUnclearedRenderbuffers( 846 bool ClearUnclearedTextures();
847
848 // Clear any uncleared level in texture.
849 // Returns false if there was a generated GL error.
850 bool ClearTexture(TextureManager::TextureInfo* info);
851
852 // Clears any uncleared attachments attached to the given frame buffer.
853 // Returns false if there was a generated GL error.
854 void ClearUnclearedAttachments(
849 GLenum target, FramebufferManager::FramebufferInfo* info); 855 GLenum target, FramebufferManager::FramebufferInfo* info);
850 856
857 // overridden from GLES2Decoder
858 virtual bool ClearLevel(
859 unsigned service_id,
860 unsigned bind_target,
861 unsigned target,
862 int level,
863 unsigned format,
864 unsigned type,
865 int width,
866 int height);
867
851 // Restore all GL state that affects clearing. 868 // Restore all GL state that affects clearing.
852 void RestoreClearState(); 869 void RestoreClearState();
853 870
854 // Remembers the state of some capabilities. 871 // Remembers the state of some capabilities.
855 // Returns: true if glEnable/glDisable should actually be called. 872 // Returns: true if glEnable/glDisable should actually be called.
856 bool SetCapabilityState(GLenum cap, bool enabled); 873 bool SetCapabilityState(GLenum cap, bool enabled);
857 874
858 // Check that the current frame buffer is complete. Generates error if not. 875 // Check that the currently bound framebuffers are valid.
859 bool CheckFramebufferComplete(const char* func_name); 876 // Generates GL error if not.
877 bool CheckBoundFramebuffersValid(const char* func_name);
878
879 // Check if a framebuffer meets our requirements.
880 bool CheckFramebufferValid(
881 FramebufferManager::FramebufferInfo* framebuffer,
882 GLenum target,
883 const char* func_name);
860 884
861 // Checks if the current program exists and is valid. If not generates the 885 // Checks if the current program exists and is valid. If not generates the
862 // appropriate GL error. Returns true if the current program is in a usable 886 // appropriate GL error. Returns true if the current program is in a usable
863 // state. 887 // state.
864 bool CheckCurrentProgram(const char* function_name); 888 bool CheckCurrentProgram(const char* function_name);
865 889
866 // Checks if the current program exists and is valid and that location is not 890 // Checks if the current program exists and is valid and that location is not
867 // -1. If the current program is not valid generates the appropriate GL 891 // -1. If the current program is not valid generates the appropriate GL
868 // error. Returns true if the current program is in a usable state and 892 // error. Returns true if the current program is in a usable state and
869 // location is not -1. 893 // location is not -1.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 // false if pname is unknown. 1105 // false if pname is unknown.
1082 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); 1106 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1083 1107
1084 // Gets the GLError through our wrapper. 1108 // Gets the GLError through our wrapper.
1085 GLenum GetGLError(); 1109 GLenum GetGLError();
1086 1110
1087 // Gets the GLError and stores it in our wrapper. Effectively 1111 // Gets the GLError and stores it in our wrapper. Effectively
1088 // this lets us peek at the error without losing it. 1112 // this lets us peek at the error without losing it.
1089 GLenum PeekGLError(); 1113 GLenum PeekGLError();
1090 1114
1091 // Sets our wrapper for the GLError.
1092 void SetGLError(GLenum error, const char* msg);
1093
1094 // Copies the real GL errors to the wrapper. This is so we can 1115 // Copies the real GL errors to the wrapper. This is so we can
1095 // make sure there are no native GL errors before calling some GL function 1116 // make sure there are no native GL errors before calling some GL function
1096 // so that on return we know any error generated was for that specific 1117 // so that on return we know any error generated was for that specific
1097 // command. 1118 // command.
1098 void CopyRealGLErrorsToWrapper(); 1119 void CopyRealGLErrorsToWrapper();
1099 1120
1100 // Clear all real GL errors. This is to prevent the client from seeing any 1121 // Clear all real GL errors. This is to prevent the client from seeing any
1101 // errors caused by GL calls that it was not responsible for issuing. 1122 // errors caused by GL calls that it was not responsible for issuing.
1102 void ClearRealGLErrors(); 1123 void ClearRealGLErrors();
1103 1124
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 case GL_READ_FRAMEBUFFER: 1197 case GL_READ_FRAMEBUFFER:
1177 info = bound_read_framebuffer_; 1198 info = bound_read_framebuffer_;
1178 break; 1199 break;
1179 default: 1200 default:
1180 NOTREACHED(); 1201 NOTREACHED();
1181 break; 1202 break;
1182 } 1203 }
1183 return (info && !info->IsDeleted()) ? info : NULL; 1204 return (info && !info->IsDeleted()) ? info : NULL;
1184 } 1205 }
1185 1206
1207 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget(
1208 GLenum target) {
1209 RenderbufferManager::RenderbufferInfo* info = NULL;
1210 switch (target) {
1211 case GL_RENDERBUFFER:
1212 info = bound_renderbuffer_;
1213 break;
1214 default:
1215 NOTREACHED();
1216 break;
1217 }
1218 return (info && !info->IsDeleted()) ? info : NULL;
1219 }
1220
1186 // Validates the program and location for a glGetUniform call and returns 1221 // Validates the program and location for a glGetUniform call and returns
1187 // a SizeResult setup to receive the result. Returns true if glGetUniform 1222 // a SizeResult setup to receive the result. Returns true if glGetUniform
1188 // should be called. 1223 // should be called.
1189 bool GetUniformSetup( 1224 bool GetUniformSetup(
1190 GLuint program, GLint location, 1225 GLuint program, GLint location,
1191 uint32 shm_id, uint32 shm_offset, 1226 uint32 shm_id, uint32 shm_offset,
1192 error::Error* error, GLuint* service_id, void** result, 1227 error::Error* error, GLuint* service_id, void** result,
1193 GLenum* result_type); 1228 GLenum* result_type);
1194 1229
1195 // Returns true if the context was just lost due to e.g. GL_ARB_robustness. 1230 // Returns true if the context was just lost due to e.g. GL_ARB_robustness.
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 DCHECK_NE(id_, 0u); 1694 DCHECK_NE(id_, 0u);
1660 ScopedGLErrorSuppressor suppressor(decoder_); 1695 ScopedGLErrorSuppressor suppressor(decoder_);
1661 ScopedFrameBufferBinder binder(decoder_, id_); 1696 ScopedFrameBufferBinder binder(decoder_, id_);
1662 GLuint attach_id = render_buffer ? render_buffer->id() : 0; 1697 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
1663 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, 1698 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1664 target, 1699 target,
1665 GL_RENDERBUFFER, 1700 GL_RENDERBUFFER,
1666 attach_id); 1701 attach_id);
1667 } 1702 }
1668 1703
1669 void FrameBuffer::Clear(GLbitfield buffers) {
1670 ScopedGLErrorSuppressor suppressor(decoder_);
1671 ScopedFrameBufferBinder binder(decoder_, id_);
1672 glClear(buffers);
1673 }
1674
1675 void FrameBuffer::Destroy() { 1704 void FrameBuffer::Destroy() {
1676 if (id_ != 0) { 1705 if (id_ != 0) {
1677 ScopedGLErrorSuppressor suppressor(decoder_); 1706 ScopedGLErrorSuppressor suppressor(decoder_);
1678 glDeleteFramebuffersEXT(1, &id_); 1707 glDeleteFramebuffersEXT(1, &id_);
1679 id_ = 0; 1708 id_ = 0;
1680 } 1709 }
1681 } 1710 }
1682 1711
1683 void FrameBuffer::Invalidate() { 1712 void FrameBuffer::Invalidate() {
1684 id_ = 0; 1713 id_ = 0;
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 bool result = context_.get() ? context_->MakeCurrent(surface_.get()) : false; 2246 bool result = context_.get() ? context_->MakeCurrent(surface_.get()) : false;
2218 if (result && WasContextLost()) { 2247 if (result && WasContextLost()) {
2219 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 2248 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
2220 result = false; 2249 result = false;
2221 } 2250 }
2222 2251
2223 return result; 2252 return result;
2224 } 2253 }
2225 2254
2226 void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { 2255 void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
2256 RenderbufferManager::RenderbufferInfo* renderbuffer =
2257 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
2227 glBindRenderbufferEXT( 2258 glBindRenderbufferEXT(
2228 GL_RENDERBUFFER, 2259 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
2229 bound_renderbuffer_ ? bound_renderbuffer_->service_id() : 0);
2230 } 2260 }
2231 2261
2232 static void RebindCurrentFramebuffer( 2262 static void RebindCurrentFramebuffer(
2233 GLenum target, 2263 GLenum target,
2234 FramebufferManager::FramebufferInfo* info, 2264 FramebufferManager::FramebufferInfo* info,
2235 FrameBuffer* offscreen_frame_buffer) { 2265 FrameBuffer* offscreen_frame_buffer) {
2236 GLuint framebuffer_id = info ? info->service_id() : 0; 2266 GLuint framebuffer_id = info ? info->service_id() : 0;
2237 2267
2238 if (framebuffer_id == 0 && offscreen_frame_buffer) { 2268 if (framebuffer_id == 0 && offscreen_frame_buffer) {
2239 framebuffer_id = offscreen_frame_buffer->id(); 2269 framebuffer_id = offscreen_frame_buffer->id();
(...skipping 28 matching lines...) Expand all
2268 if (info.bound_texture_2d) { 2298 if (info.bound_texture_2d) {
2269 last_id = info.bound_texture_2d->service_id(); 2299 last_id = info.bound_texture_2d->service_id();
2270 } else { 2300 } else {
2271 last_id = 0; 2301 last_id = 0;
2272 } 2302 }
2273 2303
2274 glBindTexture(GL_TEXTURE_2D, last_id); 2304 glBindTexture(GL_TEXTURE_2D, last_id);
2275 glActiveTexture(GL_TEXTURE0 + active_texture_unit_); 2305 glActiveTexture(GL_TEXTURE0 + active_texture_unit_);
2276 } 2306 }
2277 2307
2278 bool GLES2DecoderImpl::CheckFramebufferComplete(const char* func_name) { 2308 bool GLES2DecoderImpl::CheckFramebufferValid(
2279 if (bound_draw_framebuffer_ && bound_draw_framebuffer_->IsNotComplete()) { 2309 FramebufferManager::FramebufferInfo* framebuffer,
2280 SetGLError(GL_INVALID_FRAMEBUFFER_OPERATION, 2310 GLenum target, const char* func_name) {
2281 (std::string(func_name) + " framebuffer incomplete").c_str()); 2311 if (!framebuffer || framebuffer->IsDeleted()) {
2312 return true;
2313 }
2314
2315 GLenum completeness = framebuffer->IsPossiblyComplete();
2316 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
2317 SetGLError(
2318 GL_INVALID_FRAMEBUFFER_OPERATION,
2319 (std::string(func_name) + " framebuffer incomplete").c_str());
2282 return false; 2320 return false;
2283 } 2321 }
2322
2323 // Are all the attachments cleared?
2324 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2325 texture_manager()->HaveUnclearedMips()) {
2326 if (!framebuffer->IsCleared()) {
2327 // Can we clear them?
2328 if (glCheckFramebufferStatusEXT(target) != GL_FRAMEBUFFER_COMPLETE) {
2329 SetGLError(
2330 GL_INVALID_FRAMEBUFFER_OPERATION,
2331 (std::string(func_name) +
2332 " framebuffer incomplete (clear)").c_str());
2333 return false;
2334 }
2335 ClearUnclearedAttachments(target, framebuffer);
2336 }
2337 }
2338
2339 // NOTE: At this point we don't know if the framebuffer is complete but
2340 // we DO know that everything that needs to be cleared has been cleared.
2284 return true; 2341 return true;
2285 } 2342 }
2286 2343
2344 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
2345 if (!feature_info_->feature_flags().chromium_framebuffer_multisample) {
2346 return CheckFramebufferValid(
2347 bound_draw_framebuffer_, GL_FRAMEBUFFER_EXT, func_name);
2348 }
2349 return CheckFramebufferValid(
2350 bound_draw_framebuffer_, GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
2351 CheckFramebufferValid(
2352 bound_read_framebuffer_, GL_READ_FRAMEBUFFER_EXT, func_name);
2353 }
2354
2287 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { 2355 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
2288 if (bound_read_framebuffer_ != 0) { 2356 FramebufferManager::FramebufferInfo* framebuffer =
2357 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
2358 if (framebuffer != NULL) {
2289 const FramebufferManager::FramebufferInfo::Attachment* attachment = 2359 const FramebufferManager::FramebufferInfo::Attachment* attachment =
2290 bound_read_framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); 2360 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
2291 if (attachment) { 2361 if (attachment) {
2292 return gfx::Size(attachment->width(), attachment->height()); 2362 return gfx::Size(attachment->width(), attachment->height());
2293 } 2363 }
2294 return gfx::Size(0, 0); 2364 return gfx::Size(0, 0);
2295 } else if (offscreen_target_frame_buffer_.get()) { 2365 } else if (offscreen_target_frame_buffer_.get()) {
2296 return offscreen_size_; 2366 return offscreen_size_;
2297 } else { 2367 } else {
2298 return surface_->GetSize(); 2368 return surface_->GetSize();
2299 } 2369 }
2300 } 2370 }
2301 2371
2302 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { 2372 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
2303 if (bound_read_framebuffer_ != 0) { 2373 FramebufferManager::FramebufferInfo* framebuffer =
2304 return bound_read_framebuffer_->GetColorAttachmentFormat(); 2374 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
2375 if (framebuffer != NULL) {
2376 return framebuffer->GetColorAttachmentFormat();
2305 } else if (offscreen_target_frame_buffer_.get()) { 2377 } else if (offscreen_target_frame_buffer_.get()) {
2306 return offscreen_target_color_format_; 2378 return offscreen_target_color_format_;
2307 } else { 2379 } else {
2308 return back_buffer_color_format_; 2380 return back_buffer_color_format_;
2309 } 2381 }
2310 } 2382 }
2311 2383
2312 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { 2384 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
2313 if (bound_draw_framebuffer_ != 0) { 2385 FramebufferManager::FramebufferInfo* framebuffer =
2314 return bound_draw_framebuffer_->GetColorAttachmentFormat(); 2386 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
2387 if (framebuffer != NULL) {
2388 return framebuffer->GetColorAttachmentFormat();
2315 } else if (offscreen_target_frame_buffer_.get()) { 2389 } else if (offscreen_target_frame_buffer_.get()) {
2316 return offscreen_target_color_format_; 2390 return offscreen_target_color_format_;
2317 } else { 2391 } else {
2318 return back_buffer_color_format_; 2392 return back_buffer_color_format_;
2319 } 2393 }
2320 } 2394 }
2321 2395
2322 void GLES2DecoderImpl::UpdateParentTextureInfo() { 2396 void GLES2DecoderImpl::UpdateParentTextureInfo() {
2323 if (parent_) { 2397 if (parent_) {
2324 // Update the info about the offscreen saved color texture in the parent. 2398 // Update the info about the offscreen saved color texture in the parent.
(...skipping 10 matching lines...) Expand all
2335 feature_info_, 2409 feature_info_,
2336 info, 2410 info,
2337 GL_TEXTURE_2D, 2411 GL_TEXTURE_2D,
2338 0, // level 2412 0, // level
2339 GL_RGBA, 2413 GL_RGBA,
2340 offscreen_size_.width(), 2414 offscreen_size_.width(),
2341 offscreen_size_.height(), 2415 offscreen_size_.height(),
2342 1, // depth 2416 1, // depth
2343 0, // border 2417 0, // border
2344 GL_RGBA, 2418 GL_RGBA,
2345 GL_UNSIGNED_BYTE); 2419 GL_UNSIGNED_BYTE,
2420 true);
2346 parent_texture_manager->SetParameter( 2421 parent_texture_manager->SetParameter(
2347 feature_info_, 2422 feature_info_,
2348 info, 2423 info,
2349 GL_TEXTURE_MAG_FILTER, 2424 GL_TEXTURE_MAG_FILTER,
2350 GL_NEAREST); 2425 GL_NEAREST);
2351 parent_texture_manager->SetParameter( 2426 parent_texture_manager->SetParameter(
2352 feature_info_, 2427 feature_info_,
2353 info, 2428 info,
2354 GL_TEXTURE_MIN_FILTER, 2429 GL_TEXTURE_MIN_FILTER,
2355 GL_NEAREST); 2430 GL_NEAREST);
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 } 2871 }
2797 glBindBuffer(target, service_id); 2872 glBindBuffer(target, service_id);
2798 } 2873 }
2799 2874
2800 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() { 2875 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
2801 return (GLES2Util::GetChannelsForFormat( 2876 return (GLES2Util::GetChannelsForFormat(
2802 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0; 2877 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
2803 } 2878 }
2804 2879
2805 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() { 2880 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
2806 if (bound_draw_framebuffer_) { 2881 FramebufferManager::FramebufferInfo* framebuffer =
2807 return bound_draw_framebuffer_->HasDepthAttachment(); 2882 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
2883 if (framebuffer) {
2884 return framebuffer->HasDepthAttachment();
2808 } 2885 }
2809 if (offscreen_target_frame_buffer_.get()) { 2886 if (offscreen_target_frame_buffer_.get()) {
2810 return offscreen_target_depth_format_ != 0; 2887 return offscreen_target_depth_format_ != 0;
2811 } 2888 }
2812 return back_buffer_has_depth_; 2889 return back_buffer_has_depth_;
2813 } 2890 }
2814 2891
2815 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { 2892 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
2816 if (bound_draw_framebuffer_) { 2893 FramebufferManager::FramebufferInfo* framebuffer =
2817 return bound_draw_framebuffer_->HasStencilAttachment(); 2894 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
2895 if (framebuffer) {
2896 return framebuffer->HasStencilAttachment();
2818 } 2897 }
2819 if (offscreen_target_frame_buffer_.get()) { 2898 if (offscreen_target_frame_buffer_.get()) {
2820 return offscreen_target_stencil_format_ != 0 || 2899 return offscreen_target_stencil_format_ != 0 ||
2821 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 2900 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
2822 } 2901 }
2823 return back_buffer_has_stencil_; 2902 return back_buffer_has_stencil_;
2824 } 2903 }
2825 2904
2826 void GLES2DecoderImpl::ApplyDirtyState() { 2905 void GLES2DecoderImpl::ApplyDirtyState() {
2827 if (state_dirty_) { 2906 if (state_dirty_) {
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 *params = client_id; 3289 *params = client_id;
3211 } else { 3290 } else {
3212 *params = 0; 3291 *params = 0;
3213 } 3292 }
3214 } 3293 }
3215 return true; 3294 return true;
3216 case GL_FRAMEBUFFER_BINDING: 3295 case GL_FRAMEBUFFER_BINDING:
3217 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) 3296 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
3218 *num_written = 1; 3297 *num_written = 1;
3219 if (params) { 3298 if (params) {
3220 if (bound_draw_framebuffer_) { 3299 FramebufferManager::FramebufferInfo* framebuffer =
3300 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
3301 if (framebuffer) {
3221 GLuint client_id = 0; 3302 GLuint client_id = 0;
3222 framebuffer_manager()->GetClientId( 3303 framebuffer_manager()->GetClientId(
3223 bound_draw_framebuffer_->service_id(), &client_id); 3304 framebuffer->service_id(), &client_id);
3224 *params = client_id; 3305 *params = client_id;
3225 } else { 3306 } else {
3226 *params = 0; 3307 *params = 0;
3227 } 3308 }
3228 } 3309 }
3229 return true; 3310 return true;
3230 case GL_READ_FRAMEBUFFER_BINDING: 3311 case GL_READ_FRAMEBUFFER_BINDING:
3231 *num_written = 1; 3312 *num_written = 1;
3232 if (params) { 3313 if (params) {
3233 if (bound_read_framebuffer_) { 3314 FramebufferManager::FramebufferInfo* framebuffer =
3315 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
3316 if (framebuffer) {
3234 GLuint client_id = 0; 3317 GLuint client_id = 0;
3235 framebuffer_manager()->GetClientId( 3318 framebuffer_manager()->GetClientId(
3236 bound_read_framebuffer_->service_id(), &client_id); 3319 framebuffer->service_id(), &client_id);
3237 *params = client_id; 3320 *params = client_id;
3238 } else { 3321 } else {
3239 *params = 0; 3322 *params = 0;
3240 } 3323 }
3241 } 3324 }
3242 return true; 3325 return true;
3243 case GL_RENDERBUFFER_BINDING: 3326 case GL_RENDERBUFFER_BINDING:
3244 *num_written = 1; 3327 *num_written = 1;
3245 if (params) { 3328 if (params) {
3246 if (bound_renderbuffer_) { 3329 RenderbufferManager::RenderbufferInfo* renderbuffer =
3330 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
3331 if (renderbuffer) {
3247 GLuint client_id = 0; 3332 GLuint client_id = 0;
3248 renderbuffer_manager()->GetClientId( 3333 renderbuffer_manager()->GetClientId(
3249 bound_renderbuffer_->service_id(), &client_id); 3334 renderbuffer->service_id(), &client_id);
3250 *params = client_id; 3335 *params = client_id;
3251 } else { 3336 } else {
3252 *params = 0; 3337 *params = 0;
3253 } 3338 }
3254 } 3339 }
3255 return true; 3340 return true;
3256 case GL_CURRENT_PROGRAM: 3341 case GL_CURRENT_PROGRAM:
3257 *num_written = 1; 3342 *num_written = 1;
3258 if (params) { 3343 if (params) {
3259 if (current_program_) { 3344 if (current_program_) {
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
3557 return error::kNoError; 3642 return error::kNoError;
3558 } 3643 }
3559 if (ids == NULL) { 3644 if (ids == NULL) {
3560 return error::kOutOfBounds; 3645 return error::kOutOfBounds;
3561 } 3646 }
3562 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids); 3647 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
3563 return error::kNoError; 3648 return error::kNoError;
3564 } 3649 }
3565 3650
3566 void GLES2DecoderImpl::DoClear(GLbitfield mask) { 3651 void GLES2DecoderImpl::DoClear(GLbitfield mask) {
3567 if (CheckFramebufferComplete("glClear")) { 3652 if (CheckBoundFramebuffersValid("glClear")) {
3568 ApplyDirtyState(); 3653 ApplyDirtyState();
3569 glClear(mask); 3654 glClear(mask);
3570 } 3655 }
3571 } 3656 }
3572 3657
3573 void GLES2DecoderImpl::DoFramebufferRenderbuffer( 3658 void GLES2DecoderImpl::DoFramebufferRenderbuffer(
3574 GLenum target, GLenum attachment, GLenum renderbuffertarget, 3659 GLenum target, GLenum attachment, GLenum renderbuffertarget,
3575 GLuint client_renderbuffer_id) { 3660 GLuint client_renderbuffer_id) {
3576 FramebufferManager::FramebufferInfo* framebuffer_info = 3661 FramebufferManager::FramebufferInfo* framebuffer_info =
3577 GetFramebufferInfoForTarget(target); 3662 GetFramebufferInfoForTarget(target);
(...skipping 12 matching lines...) Expand all
3590 return; 3675 return;
3591 } 3676 }
3592 service_id = info->service_id(); 3677 service_id = info->service_id();
3593 } 3678 }
3594 CopyRealGLErrorsToWrapper(); 3679 CopyRealGLErrorsToWrapper();
3595 glFramebufferRenderbufferEXT( 3680 glFramebufferRenderbufferEXT(
3596 target, attachment, renderbuffertarget, service_id); 3681 target, attachment, renderbuffertarget, service_id);
3597 GLenum error = PeekGLError(); 3682 GLenum error = PeekGLError();
3598 if (error == GL_NO_ERROR) { 3683 if (error == GL_NO_ERROR) {
3599 framebuffer_info->AttachRenderbuffer(attachment, info); 3684 framebuffer_info->AttachRenderbuffer(attachment, info);
3600 if (service_id == 0 ||
3601 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) {
3602 if (info) {
3603 ClearUnclearedRenderbuffers(target, framebuffer_info);
3604 }
3605 }
3606 } 3685 }
3607 if (framebuffer_info == bound_draw_framebuffer_) { 3686 if (framebuffer_info == bound_draw_framebuffer_) {
3608 state_dirty_ = true; 3687 state_dirty_ = true;
3609 } 3688 }
3610 } 3689 }
3611 3690
3612 bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { 3691 bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
3613 switch (cap) { 3692 switch (cap) {
3614 case GL_SCISSOR_TEST: 3693 case GL_SCISSOR_TEST:
3615 enable_scissor_test_ = enabled; 3694 enable_scissor_test_ = enabled;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3686 void GLES2DecoderImpl::DoStencilMaskSeparate(GLenum face, GLuint mask) { 3765 void GLES2DecoderImpl::DoStencilMaskSeparate(GLenum face, GLuint mask) {
3687 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { 3766 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
3688 mask_stencil_front_ = mask; 3767 mask_stencil_front_ = mask;
3689 } 3768 }
3690 if (face == GL_BACK || face == GL_FRONT_AND_BACK) { 3769 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
3691 mask_stencil_back_ = mask; 3770 mask_stencil_back_ = mask;
3692 } 3771 }
3693 state_dirty_ = true; 3772 state_dirty_ = true;
3694 } 3773 }
3695 3774
3696 // NOTE: There's an assumption here that Texture attachments 3775 // Assumes framebuffer is complete.
3697 // are cleared because they are textures so we only need to clear 3776 void GLES2DecoderImpl::ClearUnclearedAttachments(
3698 // the renderbuffers.
3699 void GLES2DecoderImpl::ClearUnclearedRenderbuffers(
3700 GLenum target, FramebufferManager::FramebufferInfo* info) { 3777 GLenum target, FramebufferManager::FramebufferInfo* info) {
3778 DCHECK(!info->IsDeleted());
3701 if (target == GL_READ_FRAMEBUFFER_EXT) { 3779 if (target == GL_READ_FRAMEBUFFER_EXT) {
3702 // TODO(gman): bind this to the DRAW point, clear then bind back to READ 3780 // bind this to the DRAW point, clear then bind back to READ
3781 // TODO(gman): I don't think there is any guarantee that an FBO that
3782 // is complete on the READ attachment will be complete as a DRAW
3783 // attachment.
3784 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
3785 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id());
3703 } 3786 }
3704 GLbitfield clear_bits = 0; 3787 GLbitfield clear_bits = 0;
3705 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) { 3788 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
3706 glClearColor( 3789 glClearColor(
3707 0, 0, 0, 3790 0.0f, 0.0f, 0.0f,
3708 (GLES2Util::GetChannelsForFormat( 3791 (GLES2Util::GetChannelsForFormat(
3709 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0 : 1); 3792 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f);
3710 glColorMask(true, true, true, true); 3793 glColorMask(true, true, true, true);
3711 clear_bits |= GL_COLOR_BUFFER_BIT; 3794 clear_bits |= GL_COLOR_BUFFER_BIT;
3712 } 3795 }
3713 3796
3714 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || 3797 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
3715 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 3798 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
3716 glClearStencil(0); 3799 glClearStencil(0);
3717 glStencilMask(-1); 3800 glStencilMask(-1);
3718 clear_bits |= GL_STENCIL_BUFFER_BIT; 3801 clear_bits |= GL_STENCIL_BUFFER_BIT;
3719 } 3802 }
3720 3803
3721 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || 3804 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
3722 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 3805 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
3723 glClearDepth(1.0f); 3806 glClearDepth(1.0f);
3724 glDepthMask(true); 3807 glDepthMask(true);
3725 clear_bits |= GL_DEPTH_BUFFER_BIT; 3808 clear_bits |= GL_DEPTH_BUFFER_BIT;
3726 } 3809 }
3727 3810
3728 glDisable(GL_SCISSOR_TEST); 3811 glDisable(GL_SCISSOR_TEST);
3729 glClear(clear_bits); 3812 glClear(clear_bits);
3730 3813
3731 info->MarkAttachedRenderbuffersAsCleared(); 3814 info->MarkAttachmentsAsCleared(renderbuffer_manager(), texture_manager());
3732 3815
3733 RestoreClearState(); 3816 RestoreClearState();
3734 3817
3735 if (target == GL_READ_FRAMEBUFFER_EXT) { 3818 if (target == GL_READ_FRAMEBUFFER_EXT) {
3736 // TODO(gman): rebind draw. 3819 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id());
3820 FramebufferManager::FramebufferInfo*framebuffer =
3821 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
3822 glBindFramebufferEXT(
3823 GL_DRAW_FRAMEBUFFER_EXT, framebuffer ? framebuffer->service_id() : 0);
3737 } 3824 }
3738 } 3825 }
3739 3826
3740 void GLES2DecoderImpl::RestoreClearState() { 3827 void GLES2DecoderImpl::RestoreClearState() {
3741 state_dirty_ = true; 3828 state_dirty_ = true;
3742 glClearColor(clear_red_, clear_green_, clear_blue_, clear_alpha_); 3829 glClearColor(clear_red_, clear_green_, clear_blue_, clear_alpha_);
3743 glClearStencil(clear_stencil_); 3830 glClearStencil(clear_stencil_);
3744 glClearDepth(clear_depth_); 3831 glClearDepth(clear_depth_);
3745 if (enable_scissor_test_) { 3832 if (enable_scissor_test_) {
3746 glEnable(GL_SCISSOR_TEST); 3833 glEnable(GL_SCISSOR_TEST);
3747 } 3834 }
3748 } 3835 }
3749 3836
3750 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { 3837 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
3751 FramebufferManager::FramebufferInfo* info = 3838 FramebufferManager::FramebufferInfo* framebuffer =
3752 GetFramebufferInfoForTarget(target); 3839 GetFramebufferInfoForTarget(target);
3753 if (!info) { 3840 if (!framebuffer) {
3754 return GL_FRAMEBUFFER_COMPLETE; 3841 return GL_FRAMEBUFFER_COMPLETE;
3755 } 3842 }
3843 GLenum completeness = framebuffer->IsPossiblyComplete();
3844 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
3845 return completeness;
3846 }
3756 return glCheckFramebufferStatusEXT(target); 3847 return glCheckFramebufferStatusEXT(target);
3757 } 3848 }
3758 3849
3759 void GLES2DecoderImpl::DoFramebufferTexture2D( 3850 void GLES2DecoderImpl::DoFramebufferTexture2D(
3760 GLenum target, GLenum attachment, GLenum textarget, 3851 GLenum target, GLenum attachment, GLenum textarget,
3761 GLuint client_texture_id, GLint level) { 3852 GLuint client_texture_id, GLint level) {
3762 FramebufferManager::FramebufferInfo* framebuffer_info = 3853 FramebufferManager::FramebufferInfo* framebuffer_info =
3763 GetFramebufferInfoForTarget(target); 3854 GetFramebufferInfoForTarget(target);
3764 if (!framebuffer_info) { 3855 if (!framebuffer_info) {
3765 SetGLError(GL_INVALID_OPERATION, 3856 SetGLError(GL_INVALID_OPERATION,
3766 "glFramebufferTexture2D: no framebuffer bound."); 3857 "glFramebufferTexture2D: no framebuffer bound.");
3767 return; 3858 return;
3768 } 3859 }
3769 GLuint service_id = 0; 3860 GLuint service_id = 0;
3770 TextureManager::TextureInfo* info = NULL; 3861 TextureManager::TextureInfo* info = NULL;
3771 if (client_texture_id) { 3862 if (client_texture_id) {
3772 info = GetTextureInfo(client_texture_id); 3863 info = GetTextureInfo(client_texture_id);
3773 if (!info) { 3864 if (!info) {
3774 SetGLError(GL_INVALID_OPERATION, 3865 SetGLError(GL_INVALID_OPERATION,
3775 "glFramebufferTexture2D: unknown texture"); 3866 "glFramebufferTexture2D: unknown texture");
3776 return; 3867 return;
3777 } 3868 }
3778 service_id = info->service_id(); 3869 service_id = info->service_id();
3779 } 3870 }
3871
3872 if (!texture_manager()->ValidForTarget(
3873 feature_info_, textarget, level, 0, 0, 1)) {
3874 SetGLError(GL_INVALID_VALUE,
3875 "glFramebufferTexture2D: level out of range");
3876 return;
3877 }
3878
3780 CopyRealGLErrorsToWrapper(); 3879 CopyRealGLErrorsToWrapper();
3781 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); 3880 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
3782 GLenum error = PeekGLError(); 3881 GLenum error = PeekGLError();
3783 if (error == GL_NO_ERROR) { 3882 if (error == GL_NO_ERROR) {
3784 framebuffer_info->AttachTexture(attachment, info, textarget, level); 3883 framebuffer_info->AttachTexture(attachment, info, textarget, level);
3785 if (service_id != 0 &&
3786 glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) {
3787 ClearUnclearedRenderbuffers(target, framebuffer_info);
3788 }
3789 } 3884 }
3790 if (framebuffer_info == bound_draw_framebuffer_) { 3885 if (framebuffer_info == bound_draw_framebuffer_) {
3791 state_dirty_ = true; 3886 state_dirty_ = true;
3792 } 3887 }
3793 } 3888 }
3794 3889
3795 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( 3890 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
3796 GLenum target, GLenum attachment, GLenum pname, GLint* params) { 3891 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
3797 FramebufferManager::FramebufferInfo* framebuffer_info = 3892 FramebufferManager::FramebufferInfo* framebuffer_info =
3798 GetFramebufferInfoForTarget(target); 3893 GetFramebufferInfoForTarget(target);
(...skipping 19 matching lines...) Expand all
3818 } 3913 }
3819 default: 3914 default:
3820 break; 3915 break;
3821 } 3916 }
3822 *params = client_id; 3917 *params = client_id;
3823 } 3918 }
3824 } 3919 }
3825 3920
3826 void GLES2DecoderImpl::DoGetRenderbufferParameteriv( 3921 void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
3827 GLenum target, GLenum pname, GLint* params) { 3922 GLenum target, GLenum pname, GLint* params) {
3828 if (!bound_renderbuffer_) { 3923 RenderbufferManager::RenderbufferInfo* renderbuffer =
3924 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
3925 if (!renderbuffer) {
3829 SetGLError(GL_INVALID_OPERATION, 3926 SetGLError(GL_INVALID_OPERATION,
3830 "glGetRenderbufferParameteriv: no renderbuffer bound"); 3927 "glGetRenderbufferParameteriv: no renderbuffer bound");
3831 return; 3928 return;
3832 } 3929 }
3833 switch (pname) { 3930 switch (pname) {
3834 case GL_RENDERBUFFER_INTERNAL_FORMAT: 3931 case GL_RENDERBUFFER_INTERNAL_FORMAT:
3835 *params = bound_renderbuffer_->internal_format(); 3932 *params = renderbuffer->internal_format();
3836 break; 3933 break;
3837 case GL_RENDERBUFFER_WIDTH: 3934 case GL_RENDERBUFFER_WIDTH:
3838 *params = bound_renderbuffer_->width(); 3935 *params = renderbuffer->width();
3839 break; 3936 break;
3840 case GL_RENDERBUFFER_HEIGHT: 3937 case GL_RENDERBUFFER_HEIGHT:
3841 *params = bound_renderbuffer_->height(); 3938 *params = renderbuffer->height();
3842 break; 3939 break;
3843 default: 3940 default:
3844 glGetRenderbufferParameterivEXT(target, pname, params); 3941 glGetRenderbufferParameterivEXT(target, pname, params);
3845 break; 3942 break;
3846 } 3943 }
3847 } 3944 }
3848 3945
3849 void GLES2DecoderImpl::DoBlitFramebufferEXT( 3946 void GLES2DecoderImpl::DoBlitFramebufferEXT(
3850 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 3947 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
3851 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 3948 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
(...skipping 13 matching lines...) Expand all
3865 3962
3866 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( 3963 void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
3867 GLenum target, GLsizei samples, GLenum internalformat, 3964 GLenum target, GLsizei samples, GLenum internalformat,
3868 GLsizei width, GLsizei height) { 3965 GLsizei width, GLsizei height) {
3869 if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { 3966 if (!feature_info_->feature_flags().chromium_framebuffer_multisample) {
3870 SetGLError(GL_INVALID_OPERATION, 3967 SetGLError(GL_INVALID_OPERATION,
3871 "glRenderbufferStorageMultisampleEXT: function not available"); 3968 "glRenderbufferStorageMultisampleEXT: function not available");
3872 return; 3969 return;
3873 } 3970 }
3874 3971
3972 RenderbufferManager::RenderbufferInfo* renderbuffer =
3973 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
3974 if (!renderbuffer) {
3975 SetGLError(GL_INVALID_OPERATION,
3976 "glGetRenderbufferStorageMultisample: no renderbuffer bound");
3977 return;
3978 }
3979
3875 if (samples > renderbuffer_manager()->max_samples()) { 3980 if (samples > renderbuffer_manager()->max_samples()) {
3876 SetGLError(GL_INVALID_VALUE, 3981 SetGLError(GL_INVALID_VALUE,
3877 "glGetRenderbufferStorageMultisample: samples too large"); 3982 "glGetRenderbufferStorageMultisample: samples too large");
3878 return; 3983 return;
3879 } 3984 }
3880 3985
3881 if (width > renderbuffer_manager()->max_renderbuffer_size() || 3986 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
3882 height > renderbuffer_manager()->max_renderbuffer_size()) { 3987 height > renderbuffer_manager()->max_renderbuffer_size()) {
3883 SetGLError(GL_INVALID_VALUE, 3988 SetGLError(GL_INVALID_VALUE,
3884 "glGetRenderbufferStorageMultisample: size too large"); 3989 "glGetRenderbufferStorageMultisample: size too large");
(...skipping 19 matching lines...) Expand all
3904 CopyRealGLErrorsToWrapper(); 4009 CopyRealGLErrorsToWrapper();
3905 if (IsAngle()) { 4010 if (IsAngle()) {
3906 glRenderbufferStorageMultisampleANGLE( 4011 glRenderbufferStorageMultisampleANGLE(
3907 target, samples, impl_format, width, height); 4012 target, samples, impl_format, width, height);
3908 } else { 4013 } else {
3909 glRenderbufferStorageMultisampleEXT( 4014 glRenderbufferStorageMultisampleEXT(
3910 target, samples, impl_format, width, height); 4015 target, samples, impl_format, width, height);
3911 } 4016 }
3912 GLenum error = PeekGLError(); 4017 GLenum error = PeekGLError();
3913 if (error == GL_NO_ERROR) { 4018 if (error == GL_NO_ERROR) {
3914 bound_renderbuffer_->SetInfo(samples, internalformat, width, height); 4019 renderbuffer_manager()->SetInfo(
4020 renderbuffer, samples, internalformat, width, height);
3915 } 4021 }
3916 } 4022 }
3917 4023
3918 void GLES2DecoderImpl::DoRenderbufferStorage( 4024 void GLES2DecoderImpl::DoRenderbufferStorage(
3919 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 4025 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
3920 if (!bound_renderbuffer_) { 4026 RenderbufferManager::RenderbufferInfo* renderbuffer =
4027 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4028 if (!renderbuffer) {
3921 SetGLError(GL_INVALID_OPERATION, 4029 SetGLError(GL_INVALID_OPERATION,
3922 "glGetRenderbufferStorage: no renderbuffer bound"); 4030 "glGetRenderbufferStorage: no renderbuffer bound");
3923 return; 4031 return;
3924 } 4032 }
3925 4033
3926 if (width > renderbuffer_manager()->max_renderbuffer_size() || 4034 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
3927 height > renderbuffer_manager()->max_renderbuffer_size()) { 4035 height > renderbuffer_manager()->max_renderbuffer_size()) {
3928 SetGLError(GL_INVALID_VALUE, 4036 SetGLError(GL_INVALID_VALUE,
3929 "glGetRenderbufferStorage: size too large"); 4037 "glGetRenderbufferStorage: size too large");
3930 return; 4038 return;
(...skipping 12 matching lines...) Expand all
3943 case GL_RGB565: 4051 case GL_RGB565:
3944 impl_format = GL_RGB; 4052 impl_format = GL_RGB;
3945 break; 4053 break;
3946 } 4054 }
3947 } 4055 }
3948 4056
3949 CopyRealGLErrorsToWrapper(); 4057 CopyRealGLErrorsToWrapper();
3950 glRenderbufferStorageEXT(target, impl_format, width, height); 4058 glRenderbufferStorageEXT(target, impl_format, width, height);
3951 GLenum error = PeekGLError(); 4059 GLenum error = PeekGLError();
3952 if (error == GL_NO_ERROR) { 4060 if (error == GL_NO_ERROR) {
3953 bound_renderbuffer_->SetInfo(0, internalformat, width, height); 4061 renderbuffer_manager()->SetInfo(
4062 renderbuffer, 0, internalformat, width, height);
3954 } 4063 }
3955 } 4064 }
3956 4065
3957 void GLES2DecoderImpl::DoLinkProgram(GLuint program) { 4066 void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
3958 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram"); 4067 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
3959 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 4068 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
3960 program, "glLinkProgram"); 4069 program, "glLinkProgram");
3961 if (!info) { 4070 if (!info) {
3962 return; 4071 return;
3963 } 4072 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
4363 glBindTexture(texture_unit.bind_target, 4472 glBindTexture(texture_unit.bind_target,
4364 texture_info ? texture_info->service_id() : 0); 4473 texture_info ? texture_info->service_id() : 0);
4365 } 4474 }
4366 } 4475 }
4367 } 4476 }
4368 } 4477 }
4369 // Set the active texture back to whatever the user had it as. 4478 // Set the active texture back to whatever the user had it as.
4370 glActiveTexture(GL_TEXTURE0 + active_texture_unit_); 4479 glActiveTexture(GL_TEXTURE0 + active_texture_unit_);
4371 } 4480 }
4372 4481
4482 bool GLES2DecoderImpl::ClearUnclearedTextures() {
4483 // Only check if there are some uncleared textures.
4484 if (!texture_manager()->HaveUnsafeTextures()) {
4485 return true;
4486 }
4487
4488 // 1: Check all textures we are about to render with.
4489 if (current_program_) {
4490 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
4491 current_program_->sampler_indices();
4492 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
4493 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
4494 current_program_->GetUniformInfo(sampler_indices[ii]);
4495 DCHECK(uniform_info);
4496 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
4497 GLuint texture_unit_index = uniform_info->texture_units[jj];
4498 if (texture_unit_index < group_->max_texture_units()) {
4499 TextureUnit& texture_unit = texture_units_[texture_unit_index];
4500 TextureManager::TextureInfo* texture_info =
4501 texture_unit.GetInfoForSamplerType(uniform_info->type);
4502 if (texture_info && !texture_info->SafeToRenderFrom()) {
4503 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) {
4504 return false;
4505 }
4506 }
4507 }
4508 }
4509 }
4510 }
4511 return true;
4512 }
4513
4373 bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) { 4514 bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) {
4374 // NOTE: We specifically do not check current_program->IsValid() because 4515 // NOTE: We specifically do not check current_program->IsValid() because
4375 // it could never be invalid since glUseProgram would have failed. While 4516 // it could never be invalid since glUseProgram would have failed. While
4376 // glLinkProgram could later mark the program as invalid the previous 4517 // glLinkProgram could later mark the program as invalid the previous
4377 // valid program will still function if it is still the current program. 4518 // valid program will still function if it is still the current program.
4378 if (!current_program_) { 4519 if (!current_program_) {
4379 // The program does not exist. 4520 // The program does not exist.
4380 // But GL says no ERROR. 4521 // But GL says no ERROR.
4381 return false; 4522 return false;
4382 } 4523 }
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4597 GLint first = static_cast<GLint>(c.first); 4738 GLint first = static_cast<GLint>(c.first);
4598 GLsizei count = static_cast<GLsizei>(c.count); 4739 GLsizei count = static_cast<GLsizei>(c.count);
4599 if (!validators_->draw_mode.IsValid(mode)) { 4740 if (!validators_->draw_mode.IsValid(mode)) {
4600 SetGLError(GL_INVALID_ENUM, "glDrawArrays: mode GL_INVALID_ENUM"); 4741 SetGLError(GL_INVALID_ENUM, "glDrawArrays: mode GL_INVALID_ENUM");
4601 return error::kNoError; 4742 return error::kNoError;
4602 } 4743 }
4603 if (count < 0) { 4744 if (count < 0) {
4604 SetGLError(GL_INVALID_VALUE, "glDrawArrays: count < 0"); 4745 SetGLError(GL_INVALID_VALUE, "glDrawArrays: count < 0");
4605 return error::kNoError; 4746 return error::kNoError;
4606 } 4747 }
4607 if (!CheckFramebufferComplete("glDrawArrays")) { 4748 if (!CheckBoundFramebuffersValid("glDrawArrays")) {
4608 return error::kNoError; 4749 return error::kNoError;
4609 } 4750 }
4610 // We have to check this here because the prototype for glDrawArrays 4751 // We have to check this here because the prototype for glDrawArrays
4611 // is GLint not GLsizei. 4752 // is GLint not GLsizei.
4612 if (first < 0) { 4753 if (first < 0) {
4613 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); 4754 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0");
4614 return error::kNoError; 4755 return error::kNoError;
4615 } 4756 }
4616 4757
4617 if (count == 0) { 4758 if (count == 0) {
4618 return error::kNoError; 4759 return error::kNoError;
4619 } 4760 }
4620 4761
4621 GLuint max_vertex_accessed = first + count - 1; 4762 GLuint max_vertex_accessed = first + count - 1;
4622 if (IsDrawValid(max_vertex_accessed)) { 4763 if (IsDrawValid(max_vertex_accessed)) {
4764 if (!ClearUnclearedTextures()) {
4765 SetGLError(GL_INVALID_VALUE, "glDrawArrays: out of memory");
4766 return error::kNoError;
4767 }
4623 bool simulated_attrib_0 = false; 4768 bool simulated_attrib_0 = false;
4624 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { 4769 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) {
4625 return error::kNoError; 4770 return error::kNoError;
4626 } 4771 }
4627 bool simulated_fixed_attribs = false; 4772 bool simulated_fixed_attribs = false;
4628 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { 4773 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
4629 bool textures_set = SetBlackTextureForNonRenderableTextures(); 4774 bool textures_set = SetBlackTextureForNonRenderableTextures();
4630 ApplyDirtyState(); 4775 ApplyDirtyState();
4631 glDrawArrays(mode, first, count); 4776 glDrawArrays(mode, first, count);
4632 if (textures_set) { 4777 if (textures_set) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4670 } 4815 }
4671 if (!validators_->draw_mode.IsValid(mode)) { 4816 if (!validators_->draw_mode.IsValid(mode)) {
4672 SetGLError(GL_INVALID_ENUM, "glDrawElements: mode GL_INVALID_ENUM"); 4817 SetGLError(GL_INVALID_ENUM, "glDrawElements: mode GL_INVALID_ENUM");
4673 return error::kNoError; 4818 return error::kNoError;
4674 } 4819 }
4675 if (!validators_->index_type.IsValid(type)) { 4820 if (!validators_->index_type.IsValid(type)) {
4676 SetGLError(GL_INVALID_ENUM, "glDrawElements: type GL_INVALID_ENUM"); 4821 SetGLError(GL_INVALID_ENUM, "glDrawElements: type GL_INVALID_ENUM");
4677 return error::kNoError; 4822 return error::kNoError;
4678 } 4823 }
4679 4824
4680 if (!CheckFramebufferComplete("glDrawElements")) { 4825 if (!CheckBoundFramebuffersValid("glDrawElements")) {
4681 return error::kNoError; 4826 return error::kNoError;
4682 } 4827 }
4683 4828
4684 if (count == 0) { 4829 if (count == 0) {
4685 return error::kNoError; 4830 return error::kNoError;
4686 } 4831 }
4687 4832
4688 GLuint max_vertex_accessed; 4833 GLuint max_vertex_accessed;
4689 if (!bound_element_array_buffer_->GetMaxValueForRange( 4834 if (!bound_element_array_buffer_->GetMaxValueForRange(
4690 offset, count, type, &max_vertex_accessed)) { 4835 offset, count, type, &max_vertex_accessed)) {
4691 SetGLError(GL_INVALID_OPERATION, 4836 SetGLError(GL_INVALID_OPERATION,
4692 "glDrawElements: range out of bounds for buffer"); 4837 "glDrawElements: range out of bounds for buffer");
4693 return error::kNoError; 4838 return error::kNoError;
4694 } 4839 }
4695 4840
4696 if (IsDrawValid(max_vertex_accessed)) { 4841 if (IsDrawValid(max_vertex_accessed)) {
4842 if (!ClearUnclearedTextures()) {
4843 SetGLError(GL_INVALID_VALUE, "glDrawElements: out of memory");
4844 return error::kNoError;
4845 }
4697 bool simulated_attrib_0 = false; 4846 bool simulated_attrib_0 = false;
4698 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { 4847 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) {
4699 return error::kNoError; 4848 return error::kNoError;
4700 } 4849 }
4701 bool simulated_fixed_attribs = false; 4850 bool simulated_fixed_attribs = false;
4702 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { 4851 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
4703 bool textures_set = SetBlackTextureForNonRenderableTextures(); 4852 bool textures_set = SetBlackTextureForNonRenderableTextures();
4704 ApplyDirtyState(); 4853 ApplyDirtyState();
4705 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 4854 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
4706 glDrawElements(mode, count, type, indices); 4855 glDrawElements(mode, count, type, indices);
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
5369 // Get the size of the current fbo or backbuffer. 5518 // Get the size of the current fbo or backbuffer.
5370 gfx::Size max_size = GetBoundReadFrameBufferSize(); 5519 gfx::Size max_size = GetBoundReadFrameBufferSize();
5371 5520
5372 GLint max_x; 5521 GLint max_x;
5373 GLint max_y; 5522 GLint max_y;
5374 if (!SafeAdd(x, width, &max_x) || !SafeAdd(y, height, &max_y)) { 5523 if (!SafeAdd(x, width, &max_x) || !SafeAdd(y, height, &max_y)) {
5375 SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range"); 5524 SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
5376 return error::kNoError; 5525 return error::kNoError;
5377 } 5526 }
5378 5527
5528 if (!CheckBoundFramebuffersValid("glReadPixels")) {
5529 return error::kNoError;
5530 }
5531
5379 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { 5532 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
5380 // The user requested an out of range area. Get the results 1 line 5533 // The user requested an out of range area. Get the results 1 line
5381 // at a time. 5534 // at a time.
5382 uint32 temp_size; 5535 uint32 temp_size;
5383 if (!GLES2Util::ComputeImageDataSize( 5536 if (!GLES2Util::ComputeImageDataSize(
5384 width, 1, format, type, pack_alignment_, &temp_size)) { 5537 width, 1, format, type, pack_alignment_, &temp_size)) {
5385 SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range"); 5538 SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
5386 return error::kNoError; 5539 return error::kNoError;
5387 } 5540 }
5388 GLsizei unpadded_row_size = temp_size; 5541 GLsizei unpadded_row_size = temp_size;
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
5784 return; 5937 return;
5785 } 5938 }
5786 if (bufferdata_faster_than_buffersubdata_ && 5939 if (bufferdata_faster_than_buffersubdata_ &&
5787 offset == 0 && size == info->size()) { 5940 offset == 0 && size == info->size()) {
5788 glBufferData(target, size, data, info->usage()); 5941 glBufferData(target, size, data, info->usage());
5789 return; 5942 return;
5790 } 5943 }
5791 glBufferSubData(target, offset, size, data); 5944 glBufferSubData(target, offset, size, data);
5792 } 5945 }
5793 5946
5947 bool GLES2DecoderImpl::ClearLevel(
5948 unsigned service_id,
5949 unsigned bind_target,
5950 unsigned target,
5951 int level,
5952 unsigned format,
5953 unsigned type,
5954 int width,
5955 int height) {
5956 // Assumes the size has already been checked.
5957 uint32 pixels_size = 0;
5958 if (!GLES2Util::ComputeImageDataSize(
5959 width, height, format, type, unpack_alignment_, &pixels_size)) {
5960 return false;
5961 }
5962 scoped_array<char> zero(new char[pixels_size]);
5963 memset(zero.get(), 0, pixels_size);
5964 glBindTexture(bind_target, service_id);
5965 WrappedTexImage2D(
5966 target, level, format, width, height, 0, format, type, zero.get());
5967 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
5968 glBindTexture(bind_target, info ? info->service_id() : 0);
5969 return true;
5970 }
5971
5794 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( 5972 error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
5795 GLenum target, 5973 GLenum target,
5796 GLint level, 5974 GLint level,
5797 GLenum internal_format, 5975 GLenum internal_format,
5798 GLsizei width, 5976 GLsizei width,
5799 GLsizei height, 5977 GLsizei height,
5800 GLint border, 5978 GLint border,
5801 GLsizei image_size, 5979 GLsizei image_size,
5802 const void* data) { 5980 const void* data) {
5803 // TODO(gman): Validate image_size is correct for width, height and format. 5981 // TODO(gman): Validate image_size is correct for width, height and format.
(...skipping 27 matching lines...) Expand all
5831 memset(zero.get(), 0, image_size); 6009 memset(zero.get(), 0, image_size);
5832 data = zero.get(); 6010 data = zero.get();
5833 } 6011 }
5834 CopyRealGLErrorsToWrapper(); 6012 CopyRealGLErrorsToWrapper();
5835 glCompressedTexImage2D( 6013 glCompressedTexImage2D(
5836 target, level, internal_format, width, height, border, image_size, data); 6014 target, level, internal_format, width, height, border, image_size, data);
5837 GLenum error = PeekGLError(); 6015 GLenum error = PeekGLError();
5838 if (error == GL_NO_ERROR) { 6016 if (error == GL_NO_ERROR) {
5839 texture_manager()->SetLevelInfo( 6017 texture_manager()->SetLevelInfo(
5840 feature_info_, 6018 feature_info_,
5841 info, target, level, internal_format, width, height, 1, border, 0, 0); 6019 info, target, level, internal_format, width, height, 1, border, 0, 0,
6020 true);
5842 } 6021 }
5843 return error::kNoError; 6022 return error::kNoError;
5844 } 6023 }
5845 6024
5846 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( 6025 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
5847 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) { 6026 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
5848 GLenum target = static_cast<GLenum>(c.target); 6027 GLenum target = static_cast<GLenum>(c.target);
5849 GLint level = static_cast<GLint>(c.level); 6028 GLint level = static_cast<GLint>(c.level);
5850 GLenum internal_format = static_cast<GLenum>(c.internalformat); 6029 GLenum internal_format = static_cast<GLenum>(c.internalformat);
5851 GLsizei width = static_cast<GLsizei>(c.width); 6030 GLsizei width = static_cast<GLsizei>(c.width);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
6007 info->GetLevelSize(target, level, &tex_width, &tex_height) && 6186 info->GetLevelSize(target, level, &tex_width, &tex_height) &&
6008 info->GetLevelType(target, level, &tex_type, &tex_format) && 6187 info->GetLevelType(target, level, &tex_type, &tex_format) &&
6009 width == tex_width && height == tex_height && 6188 width == tex_width && height == tex_height &&
6010 type == tex_type && format == tex_format; 6189 type == tex_type && format == tex_format;
6011 6190
6012 if (level_is_same && !pixels) { 6191 if (level_is_same && !pixels) {
6013 tex_image_2d_failed_ = false; 6192 tex_image_2d_failed_ = false;
6014 return error::kNoError; 6193 return error::kNoError;
6015 } 6194 }
6016 6195
6017 scoped_array<int8> zero;
6018 if (!pixels) {
6019 zero.reset(new int8[pixels_size]);
6020 memset(zero.get(), 0, pixels_size);
6021 pixels = zero.get();
6022 }
6023
6024 if (info->IsAttachedToFramebuffer()) { 6196 if (info->IsAttachedToFramebuffer()) {
6025 state_dirty_ = true; 6197 state_dirty_ = true;
6026 } 6198 }
6027 6199
6028 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same) { 6200 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same) {
6029 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); 6201 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
6030 tex_image_2d_failed_ = false; 6202 tex_image_2d_failed_ = false;
6031 return error::kNoError; 6203 return error::kNoError;
6032 } 6204 }
6033 6205
6034 CopyRealGLErrorsToWrapper(); 6206 CopyRealGLErrorsToWrapper();
6035 WrappedTexImage2D( 6207 WrappedTexImage2D(
6036 target, level, internal_format, width, height, border, format, type, 6208 target, level, internal_format, width, height, border, format, type,
6037 pixels); 6209 pixels);
6038 GLenum error = PeekGLError(); 6210 GLenum error = PeekGLError();
6039 if (error == GL_NO_ERROR) { 6211 if (error == GL_NO_ERROR) {
6040 texture_manager()->SetLevelInfo(feature_info_, info, 6212 texture_manager()->SetLevelInfo(
6041 target, level, internal_format, width, height, 1, border, format, type); 6213 feature_info_, info,
6214 target, level, internal_format, width, height, 1, border, format, type,
6215 pixels != NULL);
6042 tex_image_2d_failed_ = false; 6216 tex_image_2d_failed_ = false;
6043 } 6217 }
6044 return error::kNoError; 6218 return error::kNoError;
6045 } 6219 }
6046 6220
6047 error::Error GLES2DecoderImpl::HandleTexImage2D( 6221 error::Error GLES2DecoderImpl::HandleTexImage2D(
6048 uint32 immediate_data_size, const gles2::TexImage2D& c) { 6222 uint32 immediate_data_size, const gles2::TexImage2D& c) {
6049 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D"); 6223 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
6050 tex_image_2d_failed_ = true; 6224 tex_image_2d_failed_ = true;
6051 GLenum target = static_cast<GLenum>(c.target); 6225 GLenum target = static_cast<GLenum>(c.target);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
6131 GL_INVALID_OPERATION, 6305 GL_INVALID_OPERATION,
6132 "glCompressdTexSubImage2D: format does not match internal format."); 6306 "glCompressdTexSubImage2D: format does not match internal format.");
6133 return; 6307 return;
6134 } 6308 }
6135 if (!info->ValidForTexture( 6309 if (!info->ValidForTexture(
6136 target, level, xoffset, yoffset, width, height, format, type)) { 6310 target, level, xoffset, yoffset, width, height, format, type)) {
6137 SetGLError(GL_INVALID_VALUE, 6311 SetGLError(GL_INVALID_VALUE,
6138 "glCompressdTexSubImage2D: bad dimensions."); 6312 "glCompressdTexSubImage2D: bad dimensions.");
6139 return; 6313 return;
6140 } 6314 }
6315 // Note: There is no need to deal with texture cleared tracking here
6316 // because the validation above means you can only get here if the level
6317 // is already a matching compressed format and in that case
6318 // CompressedTexImage2D already cleared the texture.
6141 glCompressedTexSubImage2D( 6319 glCompressedTexSubImage2D(
6142 target, level, xoffset, yoffset, width, height, format, image_size, data); 6320 target, level, xoffset, yoffset, width, height, format, image_size, data);
6143 } 6321 }
6144 6322
6145 static void Clip( 6323 static void Clip(
6146 GLint start, GLint range, GLint sourceRange, 6324 GLint start, GLint range, GLint sourceRange,
6147 GLint* out_start, GLint* out_range) { 6325 GLint* out_start, GLint* out_range) {
6148 DCHECK(out_start); 6326 DCHECK(out_start);
6149 DCHECK(out_range); 6327 DCHECK(out_range);
6150 if (start < 0) { 6328 if (start < 0) {
6151 range += start; 6329 range += start;
6152 start = 0; 6330 start = 0;
6153 } 6331 }
6154 GLint end = start + range; 6332 GLint end = start + range;
6155 if (end > sourceRange) { 6333 if (end > sourceRange) {
6156 range -= end - sourceRange; 6334 range -= end - sourceRange;
6157 } 6335 }
6158 *out_start = start; 6336 *out_start = start;
6159 *out_range = range; 6337 *out_range = range;
6160 } 6338 }
6161 6339
6162
6163 void GLES2DecoderImpl::DoCopyTexImage2D( 6340 void GLES2DecoderImpl::DoCopyTexImage2D(
6164 GLenum target, 6341 GLenum target,
6165 GLint level, 6342 GLint level,
6166 GLenum internal_format, 6343 GLenum internal_format,
6167 GLint x, 6344 GLint x,
6168 GLint y, 6345 GLint y,
6169 GLsizei width, 6346 GLsizei width,
6170 GLsizei height, 6347 GLsizei height,
6171 GLint border) { 6348 GLint border) {
6172 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 6349 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 GLint copyWidth = 0; 6383 GLint copyWidth = 0;
6207 GLint copyHeight = 0; 6384 GLint copyHeight = 0;
6208 Clip(x, width, size.width(), &copyX, &copyWidth); 6385 Clip(x, width, size.width(), &copyX, &copyWidth);
6209 Clip(y, height, size.height(), &copyY, &copyHeight); 6386 Clip(y, height, size.height(), &copyY, &copyHeight);
6210 6387
6211 if (copyX != x || 6388 if (copyX != x ||
6212 copyY != y || 6389 copyY != y ||
6213 copyWidth != width || 6390 copyWidth != width ||
6214 copyHeight != height) { 6391 copyHeight != height) {
6215 // some part was clipped so clear the texture. 6392 // some part was clipped so clear the texture.
6216 uint32 pixels_size = 0; 6393 if (!ClearLevel(
6217 if (!GLES2Util::ComputeImageDataSize( 6394 info->service_id(), info->target(),
6218 width, height, internal_format, GL_UNSIGNED_BYTE, 6395 target, level, internal_format, GL_UNSIGNED_BYTE, width, height)) {
6219 unpack_alignment_, &pixels_size)) { 6396 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big");
6220 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions too large");
6221 return; 6397 return;
6222 } 6398 }
6223 scoped_array<char> zero(new char[pixels_size]);
6224 memset(zero.get(), 0, pixels_size);
6225 glTexImage2D(target, level, internal_format, width, height, 0,
6226 internal_format, GL_UNSIGNED_BYTE, zero.get());
6227 if (copyHeight > 0 && copyWidth > 0) { 6399 if (copyHeight > 0 && copyWidth > 0) {
6228 GLint dx = copyX - x; 6400 GLint dx = copyX - x;
6229 GLint dy = copyY - y; 6401 GLint dy = copyY - y;
6230 GLint destX = dx; 6402 GLint destX = dx;
6231 GLint destY = dy; 6403 GLint destY = dy;
6232 glCopyTexSubImage2D(target, level, 6404 glCopyTexSubImage2D(target, level,
6233 destX, destY, copyX, copyY, 6405 destX, destY, copyX, copyY,
6234 copyWidth, copyHeight); 6406 copyWidth, copyHeight);
6235 } 6407 }
6236 } else { 6408 } else {
6237 glCopyTexImage2D(target, level, internal_format, 6409 glCopyTexImage2D(target, level, internal_format,
6238 copyX, copyY, copyWidth, copyHeight, border); 6410 copyX, copyY, copyWidth, copyHeight, border);
6239 } 6411 }
6240 GLenum error = PeekGLError(); 6412 GLenum error = PeekGLError();
6241 if (error == GL_NO_ERROR) { 6413 if (error == GL_NO_ERROR) {
6242 texture_manager()->SetLevelInfo( 6414 texture_manager()->SetLevelInfo(
6243 feature_info_, info, target, level, internal_format, width, height, 1, 6415 feature_info_, info, target, level, internal_format, width, height, 1,
6244 border, internal_format, GL_UNSIGNED_BYTE); 6416 border, internal_format, GL_UNSIGNED_BYTE, true);
6245 } 6417 }
6246 } 6418 }
6247 6419
6248 void GLES2DecoderImpl::DoCopyTexSubImage2D( 6420 void GLES2DecoderImpl::DoCopyTexSubImage2D(
6249 GLenum target, 6421 GLenum target,
6250 GLint level, 6422 GLint level,
6251 GLint xoffset, 6423 GLint xoffset,
6252 GLint yoffset, 6424 GLint yoffset,
6253 GLint x, 6425 GLint x,
6254 GLint y, 6426 GLint y,
(...skipping 27 matching lines...) Expand all
6282 } 6454 }
6283 6455
6284 ScopedResolvedFrameBufferBinder binder(this, false, true); 6456 ScopedResolvedFrameBufferBinder binder(this, false, true);
6285 gfx::Size size = GetBoundReadFrameBufferSize(); 6457 gfx::Size size = GetBoundReadFrameBufferSize();
6286 GLint copyX = 0; 6458 GLint copyX = 0;
6287 GLint copyY = 0; 6459 GLint copyY = 0;
6288 GLint copyWidth = 0; 6460 GLint copyWidth = 0;
6289 GLint copyHeight = 0; 6461 GLint copyHeight = 0;
6290 Clip(x, width, size.width(), &copyX, &copyWidth); 6462 Clip(x, width, size.width(), &copyX, &copyWidth);
6291 Clip(y, height, size.height(), &copyY, &copyHeight); 6463 Clip(y, height, size.height(), &copyY, &copyHeight);
6464
6465 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
6466 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D: dimensions too big");
6467 return;
6468 }
6469
6292 if (copyX != x || 6470 if (copyX != x ||
6293 copyY != y || 6471 copyY != y ||
6294 copyWidth != width || 6472 copyWidth != width ||
6295 copyHeight != height) { 6473 copyHeight != height) {
6296 // some part was clipped so clear the texture. 6474 // some part was clipped so clear the sub rect.
6297 uint32 pixels_size = 0; 6475 uint32 pixels_size = 0;
6298 if (!GLES2Util::ComputeImageDataSize( 6476 if (!GLES2Util::ComputeImageDataSize(
6299 width, height, format, type, unpack_alignment_, &pixels_size)) { 6477 width, height, format, type, unpack_alignment_, &pixels_size)) {
6300 SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D: dimensions too large"); 6478 SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D: dimensions too large");
6301 return; 6479 return;
6302 } 6480 }
6303 scoped_array<char> zero(new char[pixels_size]); 6481 scoped_array<char> zero(new char[pixels_size]);
6304 memset(zero.get(), 0, pixels_size); 6482 memset(zero.get(), 0, pixels_size);
6305 glTexSubImage2D( 6483 glTexSubImage2D(
6306 target, level, xoffset, yoffset, width, height, 6484 target, level, xoffset, yoffset, width, height,
6307 format, type, zero.get()); 6485 format, type, zero.get());
6308 } 6486 }
6487
6309 if (copyHeight > 0 && copyWidth > 0) { 6488 if (copyHeight > 0 && copyWidth > 0) {
6310 GLint dx = copyX - x; 6489 GLint dx = copyX - x;
6311 GLint dy = copyY - y; 6490 GLint dy = copyY - y;
6312 GLint destX = xoffset + dx; 6491 GLint destX = xoffset + dx;
6313 GLint destY = yoffset + dy; 6492 GLint destY = yoffset + dy;
6314 glCopyTexSubImage2D(target, level, 6493 glCopyTexSubImage2D(target, level,
6315 destX, destY, copyX, copyY, 6494 destX, destY, copyX, copyY,
6316 copyWidth, copyHeight); 6495 copyWidth, copyHeight);
6317 } 6496 }
6318 } 6497 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6363 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0) { 6542 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0) {
6364 GLsizei tex_width = 0; 6543 GLsizei tex_width = 0;
6365 GLsizei tex_height = 0; 6544 GLsizei tex_height = 0;
6366 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); 6545 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
6367 DCHECK(ok); 6546 DCHECK(ok);
6368 if (width == tex_width && height == tex_height) { 6547 if (width == tex_width && height == tex_height) {
6369 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the 6548 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
6370 // same as internal_foramt. If that changes we'll need to look them up. 6549 // same as internal_foramt. If that changes we'll need to look them up.
6371 WrappedTexImage2D( 6550 WrappedTexImage2D(
6372 target, level, format, width, height, 0, format, type, data); 6551 target, level, format, width, height, 0, format, type, data);
6552 texture_manager()->SetLevelCleared(info, target, level);
6373 return; 6553 return;
6374 } 6554 }
6375 } 6555 }
6556 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
6557 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big");
6558 return;
6559 }
6376 glTexSubImage2D( 6560 glTexSubImage2D(
6377 target, level, xoffset, yoffset, width, height, format, type, data); 6561 target, level, xoffset, yoffset, width, height, format, type, data);
6378 } 6562 }
6379 6563
6380 error::Error GLES2DecoderImpl::HandleTexSubImage2D( 6564 error::Error GLES2DecoderImpl::HandleTexSubImage2D(
6381 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { 6565 uint32 immediate_data_size, const gles2::TexSubImage2D& c) {
6382 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); 6566 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
6383 GLboolean internal = static_cast<GLboolean>(c.internal); 6567 GLboolean internal = static_cast<GLboolean>(c.internal);
6384 if (internal == GL_TRUE && tex_image_2d_failed_) 6568 if (internal == GL_TRUE && tex_image_2d_failed_)
6385 return error::kNoError; 6569 return error::kNoError;
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
7206 return error::kNoError; 7390 return error::kNoError;
7207 } 7391 }
7208 7392
7209 // Include the auto-generated part of this file. We split this because it means 7393 // Include the auto-generated part of this file. We split this because it means
7210 // we can easily edit the non-auto generated parts right here in this file 7394 // we can easily edit the non-auto generated parts right here in this file
7211 // instead of having to edit some template or the code generator. 7395 // instead of having to edit some template or the code generator.
7212 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 7396 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
7213 7397
7214 } // namespace gles2 7398 } // namespace gles2
7215 } // namespace gpu 7399 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698