OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
6206 GLint copyWidth = 0; | 6383 GLint copyWidth = 0; |
6207 GLint copyHeight = 0; | 6384 GLint copyHeight = 0; |
6208 Clip(x, width, size.width(), ©X, ©Width); | 6385 Clip(x, width, size.width(), ©X, ©Width); |
6209 Clip(y, height, size.height(), ©Y, ©Height); | 6386 Clip(y, height, size.height(), ©Y, ©Height); |
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 Loading... |
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(), ©X, ©Width); | 6462 Clip(x, width, size.width(), ©X, ©Width); |
6291 Clip(y, height, size.height(), ©Y, ©Height); | 6463 Clip(y, height, size.height(), ©Y, ©Height); |
| 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 Loading... |
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 Loading... |
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 |
OLD | NEW |