1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 6 7 #include <stdio.h> 8 9 #include <algorithm> 10 #include <list> 11 #include <map> 12 #include <stack> 13 #include <string> 14 #include <vector> 15 16 #include "base/at_exit.h" 17 #include "base/bind.h" 18 #include "base/callback_helpers.h" 19 #include "base/command_line.h" 20 #include "base/debug/trace_event.h" 21 #include "base/debug/trace_event_synthetic_delay.h" 22 #include "base/float_util.h" 23 #include "base/memory/scoped_ptr.h" 24 #include "base/numerics/safe_math.h" 25 #include "base/strings/string_number_conversions.h" 26 #include "base/strings/string_split.h" 27 #include "build/build_config.h" 28 #define GLES2_GPU_SERVICE 1 29 #include "gpu/command_buffer/common/debug_marker_manager.h" 30 #include "gpu/command_buffer/common/gles2_cmd_format.h" 31 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 32 #include "gpu/command_buffer/common/id_allocator.h" 33 #include "gpu/command_buffer/common/mailbox.h" 34 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h" 35 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" 36 #include "gpu/command_buffer/service/buffer_manager.h" 37 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 38 #include "gpu/command_buffer/service/context_group.h" 39 #include "gpu/command_buffer/service/context_state.h" 40 #include "gpu/command_buffer/service/error_state.h" 41 #include "gpu/command_buffer/service/feature_info.h" 42 #include "gpu/command_buffer/service/framebuffer_manager.h" 43 #include "gpu/command_buffer/service/gl_utils.h" 44 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" 45 #include "gpu/command_buffer/service/gles2_cmd_validation.h" 46 #include "gpu/command_buffer/service/gpu_state_tracer.h" 47 #include "gpu/command_buffer/service/gpu_switches.h" 48 #include "gpu/command_buffer/service/gpu_tracer.h" 49 #include "gpu/command_buffer/service/image_manager.h" 50 #include "gpu/command_buffer/service/mailbox_manager.h" 51 #include "gpu/command_buffer/service/memory_tracking.h" 52 #include "gpu/command_buffer/service/program_manager.h" 53 #include "gpu/command_buffer/service/query_manager.h" 54 #include "gpu/command_buffer/service/renderbuffer_manager.h" 55 #include "gpu/command_buffer/service/shader_manager.h" 56 #include "gpu/command_buffer/service/shader_translator.h" 57 #include "gpu/command_buffer/service/shader_translator_cache.h" 58 #include "gpu/command_buffer/service/texture_manager.h" 59 #include "gpu/command_buffer/service/vertex_array_manager.h" 60 #include "gpu/command_buffer/service/vertex_attrib_manager.h" 61 #include "third_party/smhasher/src/City.h" 62 #include "ui/gl/gl_fence.h" 63 #include "ui/gl/gl_image.h" 64 #include "ui/gl/gl_implementation.h" 65 #include "ui/gl/gl_surface.h" 66 67 #if defined(OS_MACOSX) 68 #include <IOSurface/IOSurfaceAPI.h> 69 // Note that this must be included after gl_bindings.h to avoid conflicts. 70 #include <OpenGL/CGLIOSurface.h> 71 #endif 72 73 #if defined(OS_WIN) 74 #include "base/win/win_util.h" 75 #endif 76 77 namespace gpu { 78 namespace gles2 { 79 80 namespace { 81 82 static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; 83 static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth"; 84 static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers"; 85 static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod"; 86 87 static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, 88 GLint rangeMax, 89 GLint precision) { 90 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16); 91 } 92 93 static void GetShaderPrecisionFormatImpl(GLenum shader_type, 94 GLenum precision_type, 95 GLint *range, GLint *precision) { 96 switch (precision_type) { 97 case GL_LOW_INT: 98 case GL_MEDIUM_INT: 99 case GL_HIGH_INT: 100 // These values are for a 32-bit twos-complement integer format. 101 range[0] = 31; 102 range[1] = 30; 103 *precision = 0; 104 break; 105 case GL_LOW_FLOAT: 106 case GL_MEDIUM_FLOAT: 107 case GL_HIGH_FLOAT: 108 // These values are for an IEEE single-precision floating-point format. 109 range[0] = 127; 110 range[1] = 127; 111 *precision = 23; 112 break; 113 default: 114 NOTREACHED(); 115 break; 116 } 117 118 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && 119 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) { 120 // This function is sometimes defined even though it's really just 121 // a stub, so we need to set range and precision as if it weren't 122 // defined before calling it. 123 // On Mac OS with some GPUs, calling this generates a 124 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2 125 // platforms. 126 glGetShaderPrecisionFormat(shader_type, precision_type, 127 range, precision); 128 129 // TODO(brianderson): Make the following official workarounds. 130 131 // Some drivers have bugs where they report the ranges as a negative number. 132 // Taking the absolute value here shouldn't hurt because negative numbers 133 // aren't expected anyway. 134 range[0] = abs(range[0]); 135 range[1] = abs(range[1]); 136 137 // If the driver reports a precision for highp float that isn't actually 138 // highp, don't pretend like it's supported because shader compilation will 139 // fail anyway. 140 if (precision_type == GL_HIGH_FLOAT && 141 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) { 142 range[0] = 0; 143 range[1] = 0; 144 *precision = 0; 145 } 146 } 147 } 148 149 static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) { 150 switch (plane_transform) { 151 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM: 152 return gfx::OVERLAY_TRANSFORM_NONE; 153 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM: 154 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; 155 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM: 156 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL; 157 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM: 158 return gfx::OVERLAY_TRANSFORM_ROTATE_90; 159 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM: 160 return gfx::OVERLAY_TRANSFORM_ROTATE_180; 161 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM: 162 return gfx::OVERLAY_TRANSFORM_ROTATE_270; 163 default: 164 return gfx::OVERLAY_TRANSFORM_INVALID; 165 } 166 } 167 168 } // namespace 169 170 class GLES2DecoderImpl; 171 172 // Local versions of the SET_GL_ERROR macros 173 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ 174 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) 175 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ 176 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ 177 function_name, value, label) 178 #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \ 179 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \ 180 function_name, pname) 181 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \ 182 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \ 183 function_name) 184 #define LOCAL_PEEK_GL_ERROR(function_name) \ 185 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name) 186 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \ 187 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name) 188 #define LOCAL_PERFORMANCE_WARNING(msg) \ 189 PerformanceWarning(__FILE__, __LINE__, msg) 190 #define LOCAL_RENDER_WARNING(msg) \ 191 RenderWarning(__FILE__, __LINE__, msg) 192 193 // Check that certain assumptions the code makes are true. There are places in 194 // the code where shared memory is passed direclty to GL. Example, glUniformiv, 195 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 196 // a few others) are 32bits. If they are not 32bits the code will have to change 197 // to call those GL functions with service side memory and then copy the results 198 // to shared memory, converting the sizes. 199 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 200 GLint_not_same_size_as_uint32); 201 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 202 GLint_not_same_size_as_uint32); 203 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT 204 GLfloat_not_same_size_as_float); 205 206 // TODO(kbr): the use of this anonymous namespace core dumps the 207 // linker on Mac OS X 10.6 when the symbol ordering file is used 208 // namespace { 209 210 // Returns the address of the first byte after a struct. 211 template <typename T> 212 const void* AddressAfterStruct(const T& pod) { 213 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 214 } 215 216 // Returns the address of the frst byte after the struct or NULL if size > 217 // immediate_data_size. 218 template <typename RETURN_TYPE, typename COMMAND_TYPE> 219 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod, 220 uint32 size, 221 uint32 immediate_data_size) { 222 return (size <= immediate_data_size) ? 223 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) : 224 NULL; 225 } 226 227 // Computes the data size for certain gl commands like glUniform. 228 bool ComputeDataSize( 229 GLuint count, 230 size_t size, 231 unsigned int elements_per_unit, 232 uint32* dst) { 233 uint32 value; 234 if (!SafeMultiplyUint32(count, size, &value)) { 235 return false; 236 } 237 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) { 238 return false; 239 } 240 *dst = value; 241 return true; 242 } 243 244 // Return true if a character belongs to the ASCII subset as defined in 245 // GLSL ES 1.0 spec section 3.1. 246 static bool CharacterIsValidForGLES(unsigned char c) { 247 // Printing characters are valid except " $ ` @ \ ' DEL. 248 if (c >= 32 && c <= 126 && 249 c != '"' && 250 c != '$' && 251 c != '`' && 252 c != '@' && 253 c != '\\' && 254 c != '\'') { 255 return true; 256 } 257 // Horizontal tab, line feed, vertical tab, form feed, carriage return 258 // are also valid. 259 if (c >= 9 && c <= 13) { 260 return true; 261 } 262 263 return false; 264 } 265 266 static bool StringIsValidForGLES(const char* str) { 267 for (; *str; ++str) { 268 if (!CharacterIsValidForGLES(*str)) { 269 return false; 270 } 271 } 272 return true; 273 } 274 275 // This class prevents any GL errors that occur when it is in scope from 276 // being reported to the client. 277 class ScopedGLErrorSuppressor { 278 public: 279 explicit ScopedGLErrorSuppressor( 280 const char* function_name, ErrorState* error_state); 281 ~ScopedGLErrorSuppressor(); 282 private: 283 const char* function_name_; 284 ErrorState* error_state_; 285 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); 286 }; 287 288 // Temporarily changes a decoder's bound texture and restore it when this 289 // object goes out of scope. Also temporarily switches to using active texture 290 // unit zero in case the client has changed that to something invalid. 291 class ScopedTextureBinder { 292 public: 293 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target); 294 ~ScopedTextureBinder(); 295 296 private: 297 ContextState* state_; 298 GLenum target_; 299 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); 300 }; 301 302 // Temporarily changes a decoder's bound render buffer and restore it when this 303 // object goes out of scope. 304 class ScopedRenderBufferBinder { 305 public: 306 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id); 307 ~ScopedRenderBufferBinder(); 308 309 private: 310 ContextState* state_; 311 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); 312 }; 313 314 // Temporarily changes a decoder's bound frame buffer and restore it when this 315 // object goes out of scope. 316 class ScopedFrameBufferBinder { 317 public: 318 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 319 ~ScopedFrameBufferBinder(); 320 321 private: 322 GLES2DecoderImpl* decoder_; 323 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); 324 }; 325 326 // Temporarily changes a decoder's bound frame buffer to a resolved version of 327 // the multisampled offscreen render buffer if that buffer is multisampled, and, 328 // if it is bound or enforce_internal_framebuffer is true. If internal is 329 // true, the resolved framebuffer is not visible to the parent. 330 class ScopedResolvedFrameBufferBinder { 331 public: 332 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, 333 bool enforce_internal_framebuffer, 334 bool internal); 335 ~ScopedResolvedFrameBufferBinder(); 336 337 private: 338 GLES2DecoderImpl* decoder_; 339 bool resolve_and_bind_; 340 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); 341 }; 342 343 class ScopedModifyPixels { 344 public: 345 explicit ScopedModifyPixels(TextureRef* ref); 346 ~ScopedModifyPixels(); 347 348 private: 349 TextureRef* ref_; 350 }; 351 352 ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) { 353 if (ref_) 354 ref_->texture()->OnWillModifyPixels(); 355 } 356 357 ScopedModifyPixels::~ScopedModifyPixels() { 358 if (ref_) 359 ref_->texture()->OnDidModifyPixels(); 360 } 361 362 class ScopedRenderTo { 363 public: 364 explicit ScopedRenderTo(Framebuffer* framebuffer); 365 ~ScopedRenderTo(); 366 367 private: 368 const Framebuffer* framebuffer_; 369 }; 370 371 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer) 372 : framebuffer_(framebuffer) { 373 if (framebuffer) 374 framebuffer_->OnWillRenderTo(); 375 } 376 377 ScopedRenderTo::~ScopedRenderTo() { 378 if (framebuffer_) 379 framebuffer_->OnDidRenderTo(); 380 } 381 382 // Encapsulates an OpenGL texture. 383 class BackTexture { 384 public: 385 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); 386 ~BackTexture(); 387 388 // Create a new render texture. 389 void Create(); 390 391 // Set the initial size and format of a render texture or resize it. 392 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero); 393 394 // Copy the contents of the currently bound frame buffer. 395 void Copy(const gfx::Size& size, GLenum format); 396 397 // Destroy the render texture. This must be explicitly called before 398 // destroying this object. 399 void Destroy(); 400 401 // Invalidate the texture. This can be used when a context is lost and it is 402 // not possible to make it current in order to free the resource. 403 void Invalidate(); 404 405 GLuint id() const { 406 return id_; 407 } 408 409 gfx::Size size() const { 410 return size_; 411 } 412 413 private: 414 MemoryTypeTracker memory_tracker_; 415 ContextState* state_; 416 size_t bytes_allocated_; 417 GLuint id_; 418 gfx::Size size_; 419 DISALLOW_COPY_AND_ASSIGN(BackTexture); 420 }; 421 422 // Encapsulates an OpenGL render buffer of any format. 423 class BackRenderbuffer { 424 public: 425 explicit BackRenderbuffer( 426 RenderbufferManager* renderbuffer_manager, 427 MemoryTracker* memory_tracker, 428 ContextState* state); 429 ~BackRenderbuffer(); 430 431 // Create a new render buffer. 432 void Create(); 433 434 // Set the initial size and format of a render buffer or resize it. 435 bool AllocateStorage(const FeatureInfo* feature_info, 436 const gfx::Size& size, 437 GLenum format, 438 GLsizei samples); 439 440 // Destroy the render buffer. This must be explicitly called before destroying 441 // this object. 442 void Destroy(); 443 444 // Invalidate the render buffer. This can be used when a context is lost and 445 // it is not possible to make it current in order to free the resource. 446 void Invalidate(); 447 448 GLuint id() const { 449 return id_; 450 } 451 452 private: 453 RenderbufferManager* renderbuffer_manager_; 454 MemoryTypeTracker memory_tracker_; 455 ContextState* state_; 456 size_t bytes_allocated_; 457 GLuint id_; 458 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer); 459 }; 460 461 // Encapsulates an OpenGL frame buffer. 462 class BackFramebuffer { 463 public: 464 explicit BackFramebuffer(GLES2DecoderImpl* decoder); 465 ~BackFramebuffer(); 466 467 // Create a new frame buffer. 468 void Create(); 469 470 // Attach a color render buffer to a frame buffer. 471 void AttachRenderTexture(BackTexture* texture); 472 473 // Attach a render buffer to a frame buffer. Note that this unbinds any 474 // currently bound frame buffer. 475 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer); 476 477 // Destroy the frame buffer. This must be explicitly called before destroying 478 // this object. 479 void Destroy(); 480 481 // Invalidate the frame buffer. This can be used when a context is lost and it 482 // is not possible to make it current in order to free the resource. 483 void Invalidate(); 484 485 // See glCheckFramebufferStatusEXT. 486 GLenum CheckStatus(); 487 488 GLuint id() const { 489 return id_; 490 } 491 492 private: 493 GLES2DecoderImpl* decoder_; 494 GLuint id_; 495 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); 496 }; 497 498 struct FenceCallback { 499 explicit FenceCallback() 500 : fence(gfx::GLFence::Create()) { 501 DCHECK(fence); 502 } 503 std::vector<base::Closure> callbacks; 504 scoped_ptr<gfx::GLFence> fence; 505 }; 506 507 class AsyncUploadTokenCompletionObserver 508 : public AsyncPixelTransferCompletionObserver { 509 public: 510 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token) 511 : async_upload_token_(async_upload_token) { 512 } 513 514 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE { 515 DCHECK(mem_params.buffer().get()); 516 void* data = mem_params.GetDataAddress(); 517 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data); 518 sync->SetAsyncUploadToken(async_upload_token_); 519 } 520 521 private: 522 virtual ~AsyncUploadTokenCompletionObserver() { 523 } 524 525 uint32 async_upload_token_; 526 527 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver); 528 }; 529 530 // } // anonymous namespace. 531 532 // static 533 const unsigned int GLES2Decoder::kDefaultStencilMask = 534 static_cast<unsigned int>(-1); 535 536 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, 537 uint32* service_texture_id) { 538 return false; 539 } 540 541 GLES2Decoder::GLES2Decoder() 542 : initialized_(false), 543 debug_(false), 544 log_commands_(false) { 545 } 546 547 GLES2Decoder::~GLES2Decoder() { 548 } 549 550 void GLES2Decoder::BeginDecoding() {} 551 552 void GLES2Decoder::EndDecoding() {} 553 554 // This class implements GLES2Decoder so we don't have to expose all the GLES2 555 // cmd stuff to outside this class. 556 class GLES2DecoderImpl : public GLES2Decoder, 557 public FramebufferManager::TextureDetachObserver, 558 public ErrorStateClient { 559 public: 560 explicit GLES2DecoderImpl(ContextGroup* group); 561 virtual ~GLES2DecoderImpl(); 562 563 // Overridden from AsyncAPIInterface. 564 virtual Error DoCommand(unsigned int command, 565 unsigned int arg_count, 566 const void* args) OVERRIDE; 567 568 virtual error::Error DoCommands(unsigned int num_commands, 569 const void* buffer, 570 int num_entries, 571 int* entries_processed) OVERRIDE; 572 573 template <bool DebugImpl> 574 error::Error DoCommandsImpl(unsigned int num_commands, 575 const void* buffer, 576 int num_entries, 577 int* entries_processed); 578 579 // Overridden from AsyncAPIInterface. 580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; 581 582 // Overridden from GLES2Decoder. 583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, 584 const scoped_refptr<gfx::GLContext>& context, 585 bool offscreen, 586 const gfx::Size& size, 587 const DisallowedFeatures& disallowed_features, 588 const std::vector<int32>& attribs) OVERRIDE; 589 virtual void Destroy(bool have_context) OVERRIDE; 590 virtual void SetSurface( 591 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE; 592 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE; 593 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE; 594 void UpdateParentTextureInfo(); 595 virtual bool MakeCurrent() OVERRIDE; 596 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; } 597 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); } 598 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); } 599 virtual Capabilities GetCapabilities() OVERRIDE; 600 virtual void RestoreState(const ContextState* prev_state) OVERRIDE; 601 602 virtual void RestoreActiveTexture() const OVERRIDE { 603 state_.RestoreActiveTexture(); 604 } 605 virtual void RestoreAllTextureUnitBindings( 606 const ContextState* prev_state) const OVERRIDE { 607 state_.RestoreAllTextureUnitBindings(prev_state); 608 } 609 virtual void RestoreActiveTextureUnitBinding( 610 unsigned int target) const OVERRIDE { 611 state_.RestoreActiveTextureUnitBinding(target); 612 } 613 virtual void RestoreBufferBindings() const OVERRIDE { 614 state_.RestoreBufferBindings(); 615 } 616 virtual void RestoreGlobalState() const OVERRIDE { 617 state_.RestoreGlobalState(NULL); 618 } 619 virtual void RestoreProgramBindings() const OVERRIDE { 620 state_.RestoreProgramBindings(); 621 } 622 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE { 623 state_.RestoreTextureUnitBindings(unit, NULL); 624 } 625 virtual void RestoreFramebufferBindings() const OVERRIDE; 626 virtual void RestoreRenderbufferBindings() OVERRIDE; 627 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE; 628 629 virtual void ClearAllAttributes() const OVERRIDE; 630 virtual void RestoreAllAttributes() const OVERRIDE; 631 632 virtual QueryManager* GetQueryManager() OVERRIDE { 633 return query_manager_.get(); 634 } 635 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { 636 return vertex_array_manager_.get(); 637 } 638 virtual ImageManager* GetImageManager() OVERRIDE { 639 return image_manager_.get(); 640 } 641 virtual bool ProcessPendingQueries() OVERRIDE; 642 virtual bool HasMoreIdleWork() OVERRIDE; 643 virtual void PerformIdleWork() OVERRIDE; 644 645 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE; 646 647 virtual void SetResizeCallback( 648 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; 649 650 virtual Logger* GetLogger() OVERRIDE; 651 652 virtual void BeginDecoding() OVERRIDE; 653 virtual void EndDecoding() OVERRIDE; 654 655 virtual ErrorState* GetErrorState() OVERRIDE; 656 virtual const ContextState* GetContextState() OVERRIDE { return &state_; } 657 658 virtual void SetShaderCacheCallback( 659 const ShaderCacheCallback& callback) OVERRIDE; 660 virtual void SetWaitSyncPointCallback( 661 const WaitSyncPointCallback& callback) OVERRIDE; 662 663 virtual AsyncPixelTransferManager* 664 GetAsyncPixelTransferManager() OVERRIDE; 665 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE; 666 virtual void SetAsyncPixelTransferManagerForTest( 667 AsyncPixelTransferManager* manager) OVERRIDE; 668 virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE; 669 void ProcessFinishedAsyncTransfers(); 670 671 virtual bool GetServiceTextureId(uint32 client_texture_id, 672 uint32* service_texture_id) OVERRIDE; 673 674 virtual uint32 GetTextureUploadCount() OVERRIDE; 675 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 676 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; 677 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; 678 679 // Restores the current state to the user's settings. 680 void RestoreCurrentFramebufferBindings(); 681 682 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. 683 void ApplyDirtyState(); 684 685 // These check the state of the currently bound framebuffer or the 686 // backbuffer if no framebuffer is bound. 687 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise 688 // check with all attached and enabled color attachments. 689 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers); 690 bool BoundFramebufferHasDepthAttachment(); 691 bool BoundFramebufferHasStencilAttachment(); 692 693 virtual error::ContextLostReason GetContextLostReason() OVERRIDE; 694 695 // Overridden from FramebufferManager::TextureDetachObserver: 696 virtual void OnTextureRefDetachedFromFramebuffer( 697 TextureRef* texture) OVERRIDE; 698 699 // Overriden from ErrorStateClient. 700 virtual void OnOutOfMemoryError() OVERRIDE; 701 702 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound. 703 void EnsureRenderbufferBound(); 704 705 // Helpers to facilitate calling into compatible extensions. 706 static void RenderbufferStorageMultisampleHelper( 707 const FeatureInfo* feature_info, 708 GLenum target, 709 GLsizei samples, 710 GLenum internal_format, 711 GLsizei width, 712 GLsizei height); 713 714 void BlitFramebufferHelper(GLint srcX0, 715 GLint srcY0, 716 GLint srcX1, 717 GLint srcY1, 718 GLint dstX0, 719 GLint dstY0, 720 GLint dstX1, 721 GLint dstY1, 722 GLbitfield mask, 723 GLenum filter); 724 725 private: 726 friend class ScopedFrameBufferBinder; 727 friend class ScopedResolvedFrameBufferBinder; 728 friend class BackFramebuffer; 729 730 // Initialize or re-initialize the shader translator. 731 bool InitializeShaderTranslator(); 732 733 void UpdateCapabilities(); 734 735 // Helpers for the glGen and glDelete functions. 736 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids); 737 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids); 738 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); 739 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); 740 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); 741 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); 742 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 743 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 744 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 745 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 746 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 747 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 748 749 // Helper for async upload token completion notification callback. 750 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, 751 uint32 sync_data_shm_id, 752 uint32 sync_data_shm_offset); 753 754 755 756 // Workarounds 757 void OnFboChanged() const; 758 void OnUseFramebuffer() const; 759 760 // TODO(gman): Cache these pointers? 761 BufferManager* buffer_manager() { 762 return group_->buffer_manager(); 763 } 764 765 RenderbufferManager* renderbuffer_manager() { 766 return group_->renderbuffer_manager(); 767 } 768 769 FramebufferManager* framebuffer_manager() { 770 return group_->framebuffer_manager(); 771 } 772 773 ProgramManager* program_manager() { 774 return group_->program_manager(); 775 } 776 777 ShaderManager* shader_manager() { 778 return group_->shader_manager(); 779 } 780 781 ShaderTranslatorCache* shader_translator_cache() { 782 return group_->shader_translator_cache(); 783 } 784 785 const TextureManager* texture_manager() const { 786 return group_->texture_manager(); 787 } 788 789 TextureManager* texture_manager() { 790 return group_->texture_manager(); 791 } 792 793 MailboxManager* mailbox_manager() { 794 return group_->mailbox_manager(); 795 } 796 797 ImageManager* image_manager() { return image_manager_.get(); } 798 799 VertexArrayManager* vertex_array_manager() { 800 return vertex_array_manager_.get(); 801 } 802 803 MemoryTracker* memory_tracker() { 804 return group_->memory_tracker(); 805 } 806 807 bool EnsureGPUMemoryAvailable(size_t estimated_size) { 808 MemoryTracker* tracker = memory_tracker(); 809 if (tracker) { 810 return tracker->EnsureGPUMemoryAvailable(estimated_size); 811 } 812 return true; 813 } 814 815 bool IsOffscreenBufferMultisampled() const { 816 return offscreen_target_samples_ > 1; 817 } 818 819 // Creates a Texture for the given texture. 820 TextureRef* CreateTexture( 821 GLuint client_id, GLuint service_id) { 822 return texture_manager()->CreateTexture(client_id, service_id); 823 } 824 825 // Gets the texture info for the given texture. Returns NULL if none exists. 826 TextureRef* GetTexture(GLuint client_id) const { 827 return texture_manager()->GetTexture(client_id); 828 } 829 830 // Deletes the texture info for the given texture. 831 void RemoveTexture(GLuint client_id) { 832 texture_manager()->RemoveTexture(client_id); 833 } 834 835 // Get the size (in pixels) of the currently bound frame buffer (either FBO 836 // or regular back buffer). 837 gfx::Size GetBoundReadFrameBufferSize(); 838 839 // Get the format of the currently bound frame buffer (either FBO or regular 840 // back buffer) 841 GLenum GetBoundReadFrameBufferTextureType(); 842 GLenum GetBoundReadFrameBufferInternalFormat(); 843 GLenum GetBoundDrawFrameBufferInternalFormat(); 844 845 // Wrapper for CompressedTexImage2D commands. 846 error::Error DoCompressedTexImage2D( 847 GLenum target, 848 GLint level, 849 GLenum internal_format, 850 GLsizei width, 851 GLsizei height, 852 GLint border, 853 GLsizei image_size, 854 const void* data); 855 856 // Wrapper for CompressedTexSubImage2D. 857 void DoCompressedTexSubImage2D( 858 GLenum target, 859 GLint level, 860 GLint xoffset, 861 GLint yoffset, 862 GLsizei width, 863 GLsizei height, 864 GLenum format, 865 GLsizei imageSize, 866 const void * data); 867 868 // Wrapper for CopyTexImage2D. 869 void DoCopyTexImage2D( 870 GLenum target, 871 GLint level, 872 GLenum internal_format, 873 GLint x, 874 GLint y, 875 GLsizei width, 876 GLsizei height, 877 GLint border); 878 879 // Wrapper for SwapBuffers. 880 void DoSwapBuffers(); 881 882 // Wrapper for CopyTexSubImage2D. 883 void DoCopyTexSubImage2D( 884 GLenum target, 885 GLint level, 886 GLint xoffset, 887 GLint yoffset, 888 GLint x, 889 GLint y, 890 GLsizei width, 891 GLsizei height); 892 893 // Validation for TexSubImage2D. 894 bool ValidateTexSubImage2D( 895 error::Error* error, 896 const char* function_name, 897 GLenum target, 898 GLint level, 899 GLint xoffset, 900 GLint yoffset, 901 GLsizei width, 902 GLsizei height, 903 GLenum format, 904 GLenum type, 905 const void * data); 906 907 // Wrapper for TexSubImage2D. 908 error::Error DoTexSubImage2D( 909 GLenum target, 910 GLint level, 911 GLint xoffset, 912 GLint yoffset, 913 GLsizei width, 914 GLsizei height, 915 GLenum format, 916 GLenum type, 917 const void * data); 918 919 // Extra validation for async tex(Sub)Image2D. 920 bool ValidateAsyncTransfer( 921 const char* function_name, 922 TextureRef* texture_ref, 923 GLenum target, 924 GLint level, 925 const void * data); 926 927 // Wrapper for TexImageIOSurface2DCHROMIUM. 928 void DoTexImageIOSurface2DCHROMIUM( 929 GLenum target, 930 GLsizei width, 931 GLsizei height, 932 GLuint io_surface_id, 933 GLuint plane); 934 935 void DoCopyTextureCHROMIUM( 936 GLenum target, 937 GLuint source_id, 938 GLuint target_id, 939 GLint level, 940 GLenum internal_format, 941 GLenum dest_type); 942 943 // Wrapper for TexStorage2DEXT. 944 void DoTexStorage2DEXT( 945 GLenum target, 946 GLint levels, 947 GLenum internal_format, 948 GLsizei width, 949 GLsizei height); 950 951 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); 952 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, 953 const GLbyte* key); 954 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref, 955 GLenum target, const GLbyte* data); 956 957 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); 958 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key, 959 GLuint client_id); 960 961 void DoBindTexImage2DCHROMIUM( 962 GLenum target, 963 GLint image_id); 964 void DoReleaseTexImage2DCHROMIUM( 965 GLenum target, 966 GLint image_id); 967 968 void DoTraceEndCHROMIUM(void); 969 970 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs); 971 972 void DoLoseContextCHROMIUM(GLenum current, GLenum other); 973 974 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix); 975 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); 976 977 // Creates a Program for the given program. 978 Program* CreateProgram( 979 GLuint client_id, GLuint service_id) { 980 return program_manager()->CreateProgram(client_id, service_id); 981 } 982 983 // Gets the program info for the given program. Returns NULL if none exists. 984 Program* GetProgram(GLuint client_id) { 985 return program_manager()->GetProgram(client_id); 986 } 987 988 #if defined(NDEBUG) 989 void LogClientServiceMapping( 990 const char* /* function_name */, 991 GLuint /* client_id */, 992 GLuint /* service_id */) { 993 } 994 template<typename T> 995 void LogClientServiceForInfo( 996 T* /* info */, GLuint /* client_id */, const char* /* function_name */) { 997 } 998 #else 999 void LogClientServiceMapping( 1000 const char* function_name, GLuint client_id, GLuint service_id) { 1001 if (service_logging_) { 1002 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name 1003 << ": client_id = " << client_id 1004 << ", service_id = " << service_id; 1005 } 1006 } 1007 template<typename T> 1008 void LogClientServiceForInfo( 1009 T* info, GLuint client_id, const char* function_name) { 1010 if (info) { 1011 LogClientServiceMapping(function_name, client_id, info->service_id()); 1012 } 1013 } 1014 #endif 1015 1016 // Gets the program info for the given program. If it's not a program 1017 // generates a GL error. Returns NULL if not program. 1018 Program* GetProgramInfoNotShader( 1019 GLuint client_id, const char* function_name) { 1020 Program* program = GetProgram(client_id); 1021 if (!program) { 1022 if (GetShader(client_id)) { 1023 LOCAL_SET_GL_ERROR( 1024 GL_INVALID_OPERATION, function_name, "shader passed for program"); 1025 } else { 1026 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program"); 1027 } 1028 } 1029 LogClientServiceForInfo(program, client_id, function_name); 1030 return program; 1031 } 1032 1033 1034 // Creates a Shader for the given shader. 1035 Shader* CreateShader( 1036 GLuint client_id, 1037 GLuint service_id, 1038 GLenum shader_type) { 1039 return shader_manager()->CreateShader( 1040 client_id, service_id, shader_type); 1041 } 1042 1043 // Gets the shader info for the given shader. Returns NULL if none exists. 1044 Shader* GetShader(GLuint client_id) { 1045 return shader_manager()->GetShader(client_id); 1046 } 1047 1048 // Gets the shader info for the given shader. If it's not a shader generates a 1049 // GL error. Returns NULL if not shader. 1050 Shader* GetShaderInfoNotProgram( 1051 GLuint client_id, const char* function_name) { 1052 Shader* shader = GetShader(client_id); 1053 if (!shader) { 1054 if (GetProgram(client_id)) { 1055 LOCAL_SET_GL_ERROR( 1056 GL_INVALID_OPERATION, function_name, "program passed for shader"); 1057 } else { 1058 LOCAL_SET_GL_ERROR( 1059 GL_INVALID_VALUE, function_name, "unknown shader"); 1060 } 1061 } 1062 LogClientServiceForInfo(shader, client_id, function_name); 1063 return shader; 1064 } 1065 1066 // Creates a buffer info for the given buffer. 1067 void CreateBuffer(GLuint client_id, GLuint service_id) { 1068 return buffer_manager()->CreateBuffer(client_id, service_id); 1069 } 1070 1071 // Gets the buffer info for the given buffer. 1072 Buffer* GetBuffer(GLuint client_id) { 1073 Buffer* buffer = buffer_manager()->GetBuffer(client_id); 1074 return buffer; 1075 } 1076 1077 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used 1078 // on glDeleteBuffers so we can make sure the user does not try to render 1079 // with deleted buffers. 1080 void RemoveBuffer(GLuint client_id); 1081 1082 // Creates a framebuffer info for the given framebuffer. 1083 void CreateFramebuffer(GLuint client_id, GLuint service_id) { 1084 return framebuffer_manager()->CreateFramebuffer(client_id, service_id); 1085 } 1086 1087 // Gets the framebuffer info for the given framebuffer. 1088 Framebuffer* GetFramebuffer(GLuint client_id) { 1089 return framebuffer_manager()->GetFramebuffer(client_id); 1090 } 1091 1092 // Removes the framebuffer info for the given framebuffer. 1093 void RemoveFramebuffer(GLuint client_id) { 1094 framebuffer_manager()->RemoveFramebuffer(client_id); 1095 } 1096 1097 // Creates a renderbuffer info for the given renderbuffer. 1098 void CreateRenderbuffer(GLuint client_id, GLuint service_id) { 1099 return renderbuffer_manager()->CreateRenderbuffer( 1100 client_id, service_id); 1101 } 1102 1103 // Gets the renderbuffer info for the given renderbuffer. 1104 Renderbuffer* GetRenderbuffer(GLuint client_id) { 1105 return renderbuffer_manager()->GetRenderbuffer(client_id); 1106 } 1107 1108 // Removes the renderbuffer info for the given renderbuffer. 1109 void RemoveRenderbuffer(GLuint client_id) { 1110 renderbuffer_manager()->RemoveRenderbuffer(client_id); 1111 } 1112 1113 // Gets the vertex attrib manager for the given vertex array. 1114 VertexAttribManager* GetVertexAttribManager(GLuint client_id) { 1115 VertexAttribManager* info = 1116 vertex_array_manager()->GetVertexAttribManager(client_id); 1117 return info; 1118 } 1119 1120 // Removes the vertex attrib manager for the given vertex array. 1121 void RemoveVertexAttribManager(GLuint client_id) { 1122 vertex_array_manager()->RemoveVertexAttribManager(client_id); 1123 } 1124 1125 // Creates a vertex attrib manager for the given vertex array. 1126 scoped_refptr<VertexAttribManager> CreateVertexAttribManager( 1127 GLuint client_id, 1128 GLuint service_id, 1129 bool client_visible) { 1130 return vertex_array_manager()->CreateVertexAttribManager( 1131 client_id, service_id, group_->max_vertex_attribs(), client_visible); 1132 } 1133 1134 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); 1135 void DoBindUniformLocationCHROMIUM( 1136 GLuint client_id, GLint location, const char* name); 1137 1138 error::Error GetAttribLocationHelper( 1139 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1140 const std::string& name_str); 1141 1142 error::Error GetUniformLocationHelper( 1143 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1144 const std::string& name_str); 1145 1146 // Helper for glShaderSource. 1147 error::Error ShaderSourceHelper( 1148 GLuint client_id, const char* data, uint32 data_size); 1149 1150 // Clear any textures used by the current program. 1151 bool ClearUnclearedTextures(); 1152 1153 // Clears any uncleared attachments attached to the given frame buffer. 1154 // Returns false if there was a generated GL error. 1155 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); 1156 1157 // overridden from GLES2Decoder 1158 virtual bool ClearLevel(unsigned service_id, 1159 unsigned bind_target, 1160 unsigned target, 1161 int level, 1162 unsigned internal_format, 1163 unsigned format, 1164 unsigned type, 1165 int width, 1166 int height, 1167 bool is_texture_immutable) OVERRIDE; 1168 1169 // Restore all GL state that affects clearing. 1170 void RestoreClearState(); 1171 1172 // Remembers the state of some capabilities. 1173 // Returns: true if glEnable/glDisable should actually be called. 1174 bool SetCapabilityState(GLenum cap, bool enabled); 1175 1176 // Check that the currently bound framebuffers are valid. 1177 // Generates GL error if not. 1178 bool CheckBoundFramebuffersValid(const char* func_name); 1179 1180 // Check that the currently bound read framebuffer has a color image 1181 // attached. Generates GL error if not. 1182 bool CheckBoundReadFramebufferColorAttachment(const char* func_name); 1183 1184 // Check if a framebuffer meets our requirements. 1185 bool CheckFramebufferValid( 1186 Framebuffer* framebuffer, 1187 GLenum target, 1188 const char* func_name); 1189 1190 // Checks if the current program exists and is valid. If not generates the 1191 // appropriate GL error. Returns true if the current program is in a usable 1192 // state. 1193 bool CheckCurrentProgram(const char* function_name); 1194 1195 // Checks if the current program exists and is valid and that location is not 1196 // -1. If the current program is not valid generates the appropriate GL 1197 // error. Returns true if the current program is in a usable state and 1198 // location is not -1. 1199 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); 1200 1201 // Gets the type of a uniform for a location in the current program. Sets GL 1202 // errors if the current program is not valid. Returns true if the current 1203 // program is valid and the location exists. Adjusts count so it 1204 // does not overflow the uniform. 1205 bool PrepForSetUniformByLocation(GLint fake_location, 1206 const char* function_name, 1207 Program::UniformApiType api_type, 1208 GLint* real_location, 1209 GLenum* type, 1210 GLsizei* count); 1211 1212 // Gets the service id for any simulated backbuffer fbo. 1213 GLuint GetBackbufferServiceId() const; 1214 1215 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv 1216 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written); 1217 1218 // Helper for glGetVertexAttrib 1219 void GetVertexAttribHelper( 1220 const VertexAttrib* attrib, GLenum pname, GLint* param); 1221 1222 // Wrapper for glCreateProgram 1223 bool CreateProgramHelper(GLuint client_id); 1224 1225 // Wrapper for glCreateShader 1226 bool CreateShaderHelper(GLenum type, GLuint client_id); 1227 1228 // Wrapper for glActiveTexture 1229 void DoActiveTexture(GLenum texture_unit); 1230 1231 // Wrapper for glAttachShader 1232 void DoAttachShader(GLuint client_program_id, GLint client_shader_id); 1233 1234 // Wrapper for glBindBuffer since we need to track the current targets. 1235 void DoBindBuffer(GLenum target, GLuint buffer); 1236 1237 // Wrapper for glBindFramebuffer since we need to track the current targets. 1238 void DoBindFramebuffer(GLenum target, GLuint framebuffer); 1239 1240 // Wrapper for glBindRenderbuffer since we need to track the current targets. 1241 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); 1242 1243 // Wrapper for glBindTexture since we need to track the current targets. 1244 void DoBindTexture(GLenum target, GLuint texture); 1245 1246 // Wrapper for glBindVertexArrayOES 1247 void DoBindVertexArrayOES(GLuint array); 1248 void EmulateVertexArrayState(); 1249 1250 // Wrapper for glBlitFramebufferCHROMIUM. 1251 void DoBlitFramebufferCHROMIUM( 1252 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1253 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1254 GLbitfield mask, GLenum filter); 1255 1256 // Wrapper for glBufferSubData. 1257 void DoBufferSubData( 1258 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); 1259 1260 // Wrapper for glCheckFramebufferStatus 1261 GLenum DoCheckFramebufferStatus(GLenum target); 1262 1263 // Wrapper for glClear 1264 error::Error DoClear(GLbitfield mask); 1265 1266 // Wrappers for various state. 1267 void DoDepthRangef(GLclampf znear, GLclampf zfar); 1268 void DoSampleCoverage(GLclampf value, GLboolean invert); 1269 1270 // Wrapper for glCompileShader. 1271 void DoCompileShader(GLuint shader); 1272 1273 // Helper for DeleteSharedIdsCHROMIUM commands. 1274 void DoDeleteSharedIdsCHROMIUM( 1275 GLuint namespace_id, GLsizei n, const GLuint* ids); 1276 1277 // Wrapper for glDetachShader 1278 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); 1279 1280 // Wrapper for glDisable 1281 void DoDisable(GLenum cap); 1282 1283 // Wrapper for glDisableVertexAttribArray. 1284 void DoDisableVertexAttribArray(GLuint index); 1285 1286 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined 1287 // attachments. 1288 void DoDiscardFramebufferEXT(GLenum target, 1289 GLsizei numAttachments, 1290 const GLenum* attachments); 1291 1292 // Wrapper for glEnable 1293 void DoEnable(GLenum cap); 1294 1295 // Wrapper for glEnableVertexAttribArray. 1296 void DoEnableVertexAttribArray(GLuint index); 1297 1298 // Wrapper for glFinish. 1299 void DoFinish(); 1300 1301 // Wrapper for glFlush. 1302 void DoFlush(); 1303 1304 // Wrapper for glFramebufferRenderbufffer. 1305 void DoFramebufferRenderbuffer( 1306 GLenum target, GLenum attachment, GLenum renderbuffertarget, 1307 GLuint renderbuffer); 1308 1309 // Wrapper for glFramebufferTexture2D. 1310 void DoFramebufferTexture2D( 1311 GLenum target, GLenum attachment, GLenum textarget, GLuint texture, 1312 GLint level); 1313 1314 // Wrapper for glFramebufferTexture2DMultisampleEXT. 1315 void DoFramebufferTexture2DMultisample( 1316 GLenum target, GLenum attachment, GLenum textarget, 1317 GLuint texture, GLint level, GLsizei samples); 1318 1319 // Common implementation for both DoFramebufferTexture2D wrappers. 1320 void DoFramebufferTexture2DCommon(const char* name, 1321 GLenum target, GLenum attachment, GLenum textarget, 1322 GLuint texture, GLint level, GLsizei samples); 1323 1324 // Wrapper for glGenerateMipmap 1325 void DoGenerateMipmap(GLenum target); 1326 1327 // Helper for GenSharedIdsCHROMIUM commands. 1328 void DoGenSharedIdsCHROMIUM( 1329 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); 1330 1331 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname 1332 // to account for different pname values defined in different extension 1333 // variants. 1334 GLenum AdjustGetPname(GLenum pname); 1335 1336 // Wrapper for DoGetBooleanv. 1337 void DoGetBooleanv(GLenum pname, GLboolean* params); 1338 1339 // Wrapper for DoGetFloatv. 1340 void DoGetFloatv(GLenum pname, GLfloat* params); 1341 1342 // Wrapper for glGetFramebufferAttachmentParameteriv. 1343 void DoGetFramebufferAttachmentParameteriv( 1344 GLenum target, GLenum attachment, GLenum pname, GLint* params); 1345 1346 // Wrapper for glGetIntegerv. 1347 void DoGetIntegerv(GLenum pname, GLint* params); 1348 1349 // Gets the max value in a range in a buffer. 1350 GLuint DoGetMaxValueInBufferCHROMIUM( 1351 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); 1352 1353 // Wrapper for glGetBufferParameteriv. 1354 void DoGetBufferParameteriv( 1355 GLenum target, GLenum pname, GLint* params); 1356 1357 // Wrapper for glGetProgramiv. 1358 void DoGetProgramiv( 1359 GLuint program_id, GLenum pname, GLint* params); 1360 1361 // Wrapper for glRenderbufferParameteriv. 1362 void DoGetRenderbufferParameteriv( 1363 GLenum target, GLenum pname, GLint* params); 1364 1365 // Wrapper for glGetShaderiv 1366 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); 1367 1368 // Wrappers for glGetTexParameter. 1369 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); 1370 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params); 1371 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname); 1372 1373 // Wrappers for glGetVertexAttrib. 1374 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); 1375 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); 1376 1377 // Wrappers for glIsXXX functions. 1378 bool DoIsEnabled(GLenum cap); 1379 bool DoIsBuffer(GLuint client_id); 1380 bool DoIsFramebuffer(GLuint client_id); 1381 bool DoIsProgram(GLuint client_id); 1382 bool DoIsRenderbuffer(GLuint client_id); 1383 bool DoIsShader(GLuint client_id); 1384 bool DoIsTexture(GLuint client_id); 1385 bool DoIsVertexArrayOES(GLuint client_id); 1386 1387 // Wrapper for glLinkProgram 1388 void DoLinkProgram(GLuint program); 1389 1390 // Helper for RegisterSharedIdsCHROMIUM. 1391 void DoRegisterSharedIdsCHROMIUM( 1392 GLuint namespace_id, GLsizei n, const GLuint* ids); 1393 1394 // Wrapper for glRenderbufferStorage. 1395 void DoRenderbufferStorage( 1396 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 1397 1398 // Handler for glRenderbufferStorageMultisampleCHROMIUM. 1399 void DoRenderbufferStorageMultisampleCHROMIUM( 1400 GLenum target, GLsizei samples, GLenum internalformat, 1401 GLsizei width, GLsizei height); 1402 1403 // Handler for glRenderbufferStorageMultisampleEXT 1404 // (multisampled_render_to_texture). 1405 void DoRenderbufferStorageMultisampleEXT( 1406 GLenum target, GLsizei samples, GLenum internalformat, 1407 GLsizei width, GLsizei height); 1408 1409 // Common validation for multisample extensions. 1410 bool ValidateRenderbufferStorageMultisample(GLsizei samples, 1411 GLenum internalformat, 1412 GLsizei width, 1413 GLsizei height); 1414 1415 // Verifies that the currently bound multisample renderbuffer is valid 1416 // Very slow! Only done on platforms with driver bugs that return invalid 1417 // buffers under memory pressure 1418 bool VerifyMultisampleRenderbufferIntegrity( 1419 GLuint renderbuffer, GLenum format); 1420 1421 // Wrapper for glReleaseShaderCompiler. 1422 void DoReleaseShaderCompiler() { } 1423 1424 // Wrappers for glTexParameter functions. 1425 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); 1426 void DoTexParameteri(GLenum target, GLenum pname, GLint param); 1427 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); 1428 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); 1429 1430 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 1431 // spec only these 2 functions can be used to set sampler uniforms. 1432 void DoUniform1i(GLint fake_location, GLint v0); 1433 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value); 1434 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value); 1435 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value); 1436 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value); 1437 1438 // Wrappers for glUniformfv because some drivers don't correctly accept 1439 // bool uniforms. 1440 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value); 1441 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value); 1442 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value); 1443 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value); 1444 1445 void DoUniformMatrix2fv( 1446 GLint fake_location, GLsizei count, GLboolean transpose, 1447 const GLfloat* value); 1448 void DoUniformMatrix3fv( 1449 GLint fake_location, GLsizei count, GLboolean transpose, 1450 const GLfloat* value); 1451 void DoUniformMatrix4fv( 1452 GLint fake_location, GLsizei count, GLboolean transpose, 1453 const GLfloat* value); 1454 1455 bool SetVertexAttribValue( 1456 const char* function_name, GLuint index, const GLfloat* value); 1457 1458 // Wrappers for glVertexAttrib?? 1459 void DoVertexAttrib1f(GLuint index, GLfloat v0); 1460 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1); 1461 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); 1462 void DoVertexAttrib4f( 1463 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 1464 void DoVertexAttrib1fv(GLuint index, const GLfloat *v); 1465 void DoVertexAttrib2fv(GLuint index, const GLfloat *v); 1466 void DoVertexAttrib3fv(GLuint index, const GLfloat *v); 1467 void DoVertexAttrib4fv(GLuint index, const GLfloat *v); 1468 1469 // Wrapper for glViewport 1470 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); 1471 1472 // Wrapper for glUseProgram 1473 void DoUseProgram(GLuint program); 1474 1475 // Wrapper for glValidateProgram. 1476 void DoValidateProgram(GLuint program_client_id); 1477 1478 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker); 1479 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group); 1480 void DoPopGroupMarkerEXT(void); 1481 1482 // Gets the number of values that will be returned by glGetXXX. Returns 1483 // false if pname is unknown. 1484 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); 1485 1486 // Checks if the current program and vertex attributes are valid for drawing. 1487 bool IsDrawValid( 1488 const char* function_name, GLuint max_vertex_accessed, bool instanced, 1489 GLsizei primcount); 1490 1491 // Returns true if successful, simulated will be true if attrib0 was 1492 // simulated. 1493 bool SimulateAttrib0( 1494 const char* function_name, GLuint max_vertex_accessed, bool* simulated); 1495 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding); 1496 1497 // If an image is bound to texture, this will call Will/DidUseTexImage 1498 // if needed. 1499 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1500 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1501 1502 // Returns false if textures were replaced. 1503 bool PrepareTexturesForRender(); 1504 void RestoreStateForTextures(); 1505 1506 // Returns true if GL_FIXED attribs were simulated. 1507 bool SimulateFixedAttribs( 1508 const char* function_name, 1509 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount); 1510 void RestoreStateForSimulatedFixedAttribs(); 1511 1512 // Handle DrawArrays and DrawElements for both instanced and non-instanced 1513 // cases (primcount is always 1 for non-instanced). 1514 error::Error DoDrawArrays( 1515 const char* function_name, 1516 bool instanced, GLenum mode, GLint first, GLsizei count, 1517 GLsizei primcount); 1518 error::Error DoDrawElements( 1519 const char* function_name, 1520 bool instanced, GLenum mode, GLsizei count, GLenum type, 1521 int32 offset, GLsizei primcount); 1522 1523 GLenum GetBindTargetForSamplerType(GLenum type) { 1524 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || 1525 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB); 1526 switch (type) { 1527 case GL_SAMPLER_2D: 1528 return GL_TEXTURE_2D; 1529 case GL_SAMPLER_CUBE: 1530 return GL_TEXTURE_CUBE_MAP; 1531 case GL_SAMPLER_EXTERNAL_OES: 1532 return GL_TEXTURE_EXTERNAL_OES; 1533 case GL_SAMPLER_2D_RECT_ARB: 1534 return GL_TEXTURE_RECTANGLE_ARB; 1535 } 1536 1537 NOTREACHED(); 1538 return 0; 1539 } 1540 1541 // Gets the framebuffer info for a particular target. 1542 Framebuffer* GetFramebufferInfoForTarget(GLenum target) { 1543 Framebuffer* framebuffer = NULL; 1544 switch (target) { 1545 case GL_FRAMEBUFFER: 1546 case GL_DRAW_FRAMEBUFFER_EXT: 1547 framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); 1548 break; 1549 case GL_READ_FRAMEBUFFER_EXT: 1550 framebuffer = framebuffer_state_.bound_read_framebuffer.get(); 1551 break; 1552 default: 1553 NOTREACHED(); 1554 break; 1555 } 1556 return framebuffer; 1557 } 1558 1559 Renderbuffer* GetRenderbufferInfoForTarget( 1560 GLenum target) { 1561 Renderbuffer* renderbuffer = NULL; 1562 switch (target) { 1563 case GL_RENDERBUFFER: 1564 renderbuffer = state_.bound_renderbuffer.get(); 1565 break; 1566 default: 1567 NOTREACHED(); 1568 break; 1569 } 1570 return renderbuffer; 1571 } 1572 1573 // Validates the program and location for a glGetUniform call and returns 1574 // a SizeResult setup to receive the result. Returns true if glGetUniform 1575 // should be called. 1576 bool GetUniformSetup( 1577 GLuint program, GLint fake_location, 1578 uint32 shm_id, uint32 shm_offset, 1579 error::Error* error, GLint* real_location, GLuint* service_id, 1580 void** result, GLenum* result_type); 1581 1582 virtual bool WasContextLost() OVERRIDE; 1583 virtual bool WasContextLostByRobustnessExtension() OVERRIDE; 1584 virtual void LoseContext(uint32 reset_status) OVERRIDE; 1585 1586 #if defined(OS_MACOSX) 1587 void ReleaseIOSurfaceForTexture(GLuint texture_id); 1588 #endif 1589 1590 bool ValidateCompressedTexDimensions( 1591 const char* function_name, 1592 GLint level, GLsizei width, GLsizei height, GLenum format); 1593 bool ValidateCompressedTexFuncData( 1594 const char* function_name, 1595 GLsizei width, GLsizei height, GLenum format, size_t size); 1596 bool ValidateCompressedTexSubDimensions( 1597 const char* function_name, 1598 GLenum target, GLint level, GLint xoffset, GLint yoffset, 1599 GLsizei width, GLsizei height, GLenum format, 1600 Texture* texture); 1601 1602 void RenderWarning(const char* filename, int line, const std::string& msg); 1603 void PerformanceWarning( 1604 const char* filename, int line, const std::string& msg); 1605 1606 const FeatureInfo::FeatureFlags& features() const { 1607 return feature_info_->feature_flags(); 1608 } 1609 1610 const FeatureInfo::Workarounds& workarounds() const { 1611 return feature_info_->workarounds(); 1612 } 1613 1614 bool ShouldDeferDraws() { 1615 return !offscreen_target_frame_buffer_.get() && 1616 framebuffer_state_.bound_draw_framebuffer.get() == NULL && 1617 surface_->DeferDraws(); 1618 } 1619 1620 bool ShouldDeferReads() { 1621 return !offscreen_target_frame_buffer_.get() && 1622 framebuffer_state_.bound_read_framebuffer.get() == NULL && 1623 surface_->DeferDraws(); 1624 } 1625 1626 error::Error WillAccessBoundFramebufferForDraw() { 1627 if (ShouldDeferDraws()) 1628 return error::kDeferCommandUntilLater; 1629 if (!offscreen_target_frame_buffer_.get() && 1630 !framebuffer_state_.bound_draw_framebuffer.get() && 1631 !surface_->SetBackbufferAllocation(true)) 1632 return error::kLostContext; 1633 return error::kNoError; 1634 } 1635 1636 error::Error WillAccessBoundFramebufferForRead() { 1637 if (ShouldDeferReads()) 1638 return error::kDeferCommandUntilLater; 1639 if (!offscreen_target_frame_buffer_.get() && 1640 !framebuffer_state_.bound_read_framebuffer.get() && 1641 !surface_->SetBackbufferAllocation(true)) 1642 return error::kLostContext; 1643 return error::kNoError; 1644 } 1645 1646 // Set remaining commands to process to 0 to force DoCommands to return 1647 // and allow context preemption and GPU watchdog checks in GpuScheduler(). 1648 void ExitCommandProcessingEarly() { commands_to_process_ = 0; } 1649 1650 void ProcessPendingReadPixels(); 1651 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); 1652 1653 // Generate a member function prototype for each command in an automated and 1654 // typesafe way. 1655 #define GLES2_CMD_OP(name) \ 1656 Error Handle##name(uint32 immediate_data_size, const void* data); 1657 1658 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1659 1660 #undef GLES2_CMD_OP 1661 1662 // The GL context this decoder renders to on behalf of the client. 1663 scoped_refptr<gfx::GLSurface> surface_; 1664 scoped_refptr<gfx::GLContext> context_; 1665 1666 // The ContextGroup for this decoder uses to track resources. 1667 scoped_refptr<ContextGroup> group_; 1668 1669 DebugMarkerManager debug_marker_manager_; 1670 Logger logger_; 1671 1672 // All the state for this context. 1673 ContextState state_; 1674 1675 // Current width and height of the offscreen frame buffer. 1676 gfx::Size offscreen_size_; 1677 1678 // Util to help with GL. 1679 GLES2Util util_; 1680 1681 // unpack flip y as last set by glPixelStorei 1682 bool unpack_flip_y_; 1683 1684 // unpack (un)premultiply alpha as last set by glPixelStorei 1685 bool unpack_premultiply_alpha_; 1686 bool unpack_unpremultiply_alpha_; 1687 1688 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not). 1689 GLuint attrib_0_buffer_id_; 1690 1691 // The value currently in attrib_0. 1692 Vec4 attrib_0_value_; 1693 1694 // Whether or not the attrib_0 buffer holds the attrib_0_value. 1695 bool attrib_0_buffer_matches_value_; 1696 1697 // The size of attrib 0. 1698 GLsizei attrib_0_size_; 1699 1700 // The buffer used to simulate GL_FIXED attribs. 1701 GLuint fixed_attrib_buffer_id_; 1702 1703 // The size of fiixed attrib buffer. 1704 GLsizei fixed_attrib_buffer_size_; 1705 1706 // The offscreen frame buffer that the client renders to. With EGL, the 1707 // depth and stencil buffers are separate. With regular GL there is a single 1708 // packed depth stencil buffer in offscreen_target_depth_render_buffer_. 1709 // offscreen_target_stencil_render_buffer_ is unused. 1710 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_; 1711 scoped_ptr<BackTexture> offscreen_target_color_texture_; 1712 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_; 1713 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_; 1714 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_; 1715 GLenum offscreen_target_color_format_; 1716 GLenum offscreen_target_depth_format_; 1717 GLenum offscreen_target_stencil_format_; 1718 GLsizei offscreen_target_samples_; 1719 GLboolean offscreen_target_buffer_preserved_; 1720 1721 // The copy that is saved when SwapBuffers is called. 1722 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_; 1723 scoped_ptr<BackTexture> offscreen_saved_color_texture_; 1724 scoped_refptr<TextureRef> 1725 offscreen_saved_color_texture_info_; 1726 1727 // The copy that is used as the destination for multi-sample resolves. 1728 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_; 1729 scoped_ptr<BackTexture> offscreen_resolved_color_texture_; 1730 GLenum offscreen_saved_color_format_; 1731 1732 scoped_ptr<QueryManager> query_manager_; 1733 1734 scoped_ptr<VertexArrayManager> vertex_array_manager_; 1735 1736 scoped_ptr<ImageManager> image_manager_; 1737 1738 base::Callback<void(gfx::Size, float)> resize_callback_; 1739 1740 WaitSyncPointCallback wait_sync_point_callback_; 1741 1742 ShaderCacheCallback shader_cache_callback_; 1743 1744 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_; 1745 1746 // The format of the back buffer_ 1747 GLenum back_buffer_color_format_; 1748 bool back_buffer_has_depth_; 1749 bool back_buffer_has_stencil_; 1750 1751 bool surfaceless_; 1752 1753 // Backbuffer attachments that are currently undefined. 1754 uint32 backbuffer_needs_clear_bits_; 1755 1756 // The current decoder error communicates the decoder error through command 1757 // processing functions that do not return the error value. Should be set only 1758 // if not returning an error. 1759 error::Error current_decoder_error_; 1760 1761 bool use_shader_translator_; 1762 scoped_refptr<ShaderTranslator> vertex_translator_; 1763 scoped_refptr<ShaderTranslator> fragment_translator_; 1764 1765 DisallowedFeatures disallowed_features_; 1766 1767 // Cached from ContextGroup 1768 const Validators* validators_; 1769 scoped_refptr<FeatureInfo> feature_info_; 1770 1771 int frame_number_; 1772 1773 // Number of commands remaining to be processed in DoCommands(). 1774 int commands_to_process_; 1775 1776 bool has_robustness_extension_; 1777 GLenum reset_status_; 1778 bool reset_by_robustness_extension_; 1779 bool supports_post_sub_buffer_; 1780 1781 // These flags are used to override the state of the shared feature_info_ 1782 // member. Because the same FeatureInfo instance may be shared among many 1783 // contexts, the assumptions on the availablity of extensions in WebGL 1784 // contexts may be broken. These flags override the shared state to preserve 1785 // WebGL semantics. 1786 bool force_webgl_glsl_validation_; 1787 bool derivatives_explicitly_enabled_; 1788 bool frag_depth_explicitly_enabled_; 1789 bool draw_buffers_explicitly_enabled_; 1790 bool shader_texture_lod_explicitly_enabled_; 1791 1792 bool compile_shader_always_succeeds_; 1793 1794 // An optional behaviour to lose the context and group when OOM. 1795 bool lose_context_when_out_of_memory_; 1796 1797 // Log extra info. 1798 bool service_logging_; 1799 1800 #if defined(OS_MACOSX) 1801 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap; 1802 TextureToIOSurfaceMap texture_to_io_surface_map_; 1803 #endif 1804 1805 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; 1806 1807 // Cached values of the currently assigned viewport dimensions. 1808 GLsizei viewport_max_width_; 1809 GLsizei viewport_max_height_; 1810 1811 // Command buffer stats. 1812 base::TimeDelta total_processing_commands_time_; 1813 1814 // States related to each manager. 1815 DecoderTextureState texture_state_; 1816 DecoderFramebufferState framebuffer_state_; 1817 1818 scoped_ptr<GPUTracer> gpu_tracer_; 1819 scoped_ptr<GPUStateTracer> gpu_state_tracer_; 1820 const unsigned char* cb_command_trace_category_; 1821 int gpu_trace_level_; 1822 bool gpu_trace_commands_; 1823 bool gpu_debug_commands_; 1824 1825 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; 1826 1827 // Used to validate multisample renderbuffers if needed 1828 GLuint validation_texture_; 1829 GLuint validation_fbo_multisample_; 1830 GLuint validation_fbo_; 1831 1832 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)( 1833 uint32 immediate_data_size, 1834 const void* data); 1835 1836 // A struct to hold info about each command. 1837 struct CommandInfo { 1838 CmdHandler cmd_handler; 1839 uint8 arg_flags; // How to handle the arguments for this command 1840 uint8 cmd_flags; // How to handle this command 1841 uint16 arg_count; // How many arguments are expected for this command. 1842 }; 1843 1844 // A table of CommandInfo for all the commands. 1845 static const CommandInfo command_info[kNumCommands - kStartPoint]; 1846 1847 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 1848 }; 1849 1850 const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = { 1851 #define GLES2_CMD_OP(name) \ 1852 { \ 1853 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \ 1854 cmds::name::cmd_flags, \ 1855 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \ 1856 } \ 1857 , /* NOLINT */ 1858 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1859 #undef GLES2_CMD_OP 1860 }; 1861 1862 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( 1863 const char* function_name, ErrorState* error_state) 1864 : function_name_(function_name), 1865 error_state_(error_state) { 1866 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_); 1867 } 1868 1869 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { 1870 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_); 1871 } 1872 1873 static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) { 1874 TextureUnit& info = state->texture_units[0]; 1875 GLuint last_id; 1876 scoped_refptr<TextureRef> texture_ref; 1877 switch (target) { 1878 case GL_TEXTURE_2D: 1879 texture_ref = info.bound_texture_2d; 1880 break; 1881 case GL_TEXTURE_CUBE_MAP: 1882 texture_ref = info.bound_texture_cube_map; 1883 break; 1884 case GL_TEXTURE_EXTERNAL_OES: 1885 texture_ref = info.bound_texture_external_oes; 1886 break; 1887 case GL_TEXTURE_RECTANGLE_ARB: 1888 texture_ref = info.bound_texture_rectangle_arb; 1889 break; 1890 default: 1891 NOTREACHED(); 1892 break; 1893 } 1894 if (texture_ref.get()) { 1895 last_id = texture_ref->service_id(); 1896 } else { 1897 last_id = 0; 1898 } 1899 1900 glBindTexture(target, last_id); 1901 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit); 1902 } 1903 1904 ScopedTextureBinder::ScopedTextureBinder(ContextState* state, 1905 GLuint id, 1906 GLenum target) 1907 : state_(state), 1908 target_(target) { 1909 ScopedGLErrorSuppressor suppressor( 1910 "ScopedTextureBinder::ctor", state_->GetErrorState()); 1911 1912 // TODO(apatrick): Check if there are any other states that need to be reset 1913 // before binding a new texture. 1914 glActiveTexture(GL_TEXTURE0); 1915 glBindTexture(target, id); 1916 } 1917 1918 ScopedTextureBinder::~ScopedTextureBinder() { 1919 ScopedGLErrorSuppressor suppressor( 1920 "ScopedTextureBinder::dtor", state_->GetErrorState()); 1921 RestoreCurrentTextureBindings(state_, target_); 1922 } 1923 1924 ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state, 1925 GLuint id) 1926 : state_(state) { 1927 ScopedGLErrorSuppressor suppressor( 1928 "ScopedRenderBufferBinder::ctor", state_->GetErrorState()); 1929 glBindRenderbufferEXT(GL_RENDERBUFFER, id); 1930 } 1931 1932 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { 1933 ScopedGLErrorSuppressor suppressor( 1934 "ScopedRenderBufferBinder::dtor", state_->GetErrorState()); 1935 state_->RestoreRenderbufferBindings(); 1936 } 1937 1938 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, 1939 GLuint id) 1940 : decoder_(decoder) { 1941 ScopedGLErrorSuppressor suppressor( 1942 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState()); 1943 glBindFramebufferEXT(GL_FRAMEBUFFER, id); 1944 decoder->OnFboChanged(); 1945 } 1946 1947 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { 1948 ScopedGLErrorSuppressor suppressor( 1949 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState()); 1950 decoder_->RestoreCurrentFramebufferBindings(); 1951 } 1952 1953 ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( 1954 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) 1955 : decoder_(decoder) { 1956 resolve_and_bind_ = ( 1957 decoder_->offscreen_target_frame_buffer_.get() && 1958 decoder_->IsOffscreenBufferMultisampled() && 1959 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() || 1960 enforce_internal_framebuffer)); 1961 if (!resolve_and_bind_) 1962 return; 1963 1964 ScopedGLErrorSuppressor suppressor( 1965 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState()); 1966 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 1967 decoder_->offscreen_target_frame_buffer_->id()); 1968 GLuint targetid; 1969 if (internal) { 1970 if (!decoder_->offscreen_resolved_frame_buffer_.get()) { 1971 decoder_->offscreen_resolved_frame_buffer_.reset( 1972 new BackFramebuffer(decoder_)); 1973 decoder_->offscreen_resolved_frame_buffer_->Create(); 1974 decoder_->offscreen_resolved_color_texture_.reset( 1975 new BackTexture(decoder->memory_tracker(), &decoder->state_)); 1976 decoder_->offscreen_resolved_color_texture_->Create(); 1977 1978 DCHECK(decoder_->offscreen_saved_color_format_); 1979 decoder_->offscreen_resolved_color_texture_->AllocateStorage( 1980 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_, 1981 false); 1982 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture( 1983 decoder_->offscreen_resolved_color_texture_.get()); 1984 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() != 1985 GL_FRAMEBUFFER_COMPLETE) { 1986 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed " 1987 << "because offscreen resolved FBO was incomplete."; 1988 return; 1989 } 1990 } 1991 targetid = decoder_->offscreen_resolved_frame_buffer_->id(); 1992 } else { 1993 targetid = decoder_->offscreen_saved_frame_buffer_->id(); 1994 } 1995 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid); 1996 const int width = decoder_->offscreen_size_.width(); 1997 const int height = decoder_->offscreen_size_.height(); 1998 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 1999 decoder->BlitFramebufferHelper(0, 2000 0, 2001 width, 2002 height, 2003 0, 2004 0, 2005 width, 2006 height, 2007 GL_COLOR_BUFFER_BIT, 2008 GL_NEAREST); 2009 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); 2010 } 2011 2012 ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { 2013 if (!resolve_and_bind_) 2014 return; 2015 2016 ScopedGLErrorSuppressor suppressor( 2017 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState()); 2018 decoder_->RestoreCurrentFramebufferBindings(); 2019 if (decoder_->state_.enable_flags.scissor_test) { 2020 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 2021 } 2022 } 2023 2024 BackTexture::BackTexture( 2025 MemoryTracker* memory_tracker, 2026 ContextState* state) 2027 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), 2028 state_(state), 2029 bytes_allocated_(0), 2030 id_(0) { 2031 } 2032 2033 BackTexture::~BackTexture() { 2034 // This does not destroy the render texture because that would require that 2035 // the associated GL context was current. Just check that it was explicitly 2036 // destroyed. 2037 DCHECK_EQ(id_, 0u); 2038 } 2039 2040 void BackTexture::Create() { 2041 ScopedGLErrorSuppressor suppressor("BackTexture::Create", 2042 state_->GetErrorState()); 2043 Destroy(); 2044 glGenTextures(1, &id_); 2045 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 2046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 2047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2049 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 2050 2051 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is 2052 // never called on an offscreen context, no data will ever be uploaded to the 2053 // saved offscreen color texture (it is deferred until to when SwapBuffers 2054 // is called). My idea is that some nvidia drivers might have a bug where 2055 // deleting a texture that has never been populated might cause a 2056 // crash. 2057 glTexImage2D( 2058 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 2059 2060 bytes_allocated_ = 16u * 16u * 4u; 2061 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2062 } 2063 2064 bool BackTexture::AllocateStorage( 2065 const gfx::Size& size, GLenum format, bool zero) { 2066 DCHECK_NE(id_, 0u); 2067 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", 2068 state_->GetErrorState()); 2069 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 2070 uint32 image_size = 0; 2071 GLES2Util::ComputeImageDataSizes( 2072 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, 2073 NULL, NULL); 2074 2075 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { 2076 return false; 2077 } 2078 2079 scoped_ptr<char[]> zero_data; 2080 if (zero) { 2081 zero_data.reset(new char[image_size]); 2082 memset(zero_data.get(), 0, image_size); 2083 } 2084 2085 glTexImage2D(GL_TEXTURE_2D, 2086 0, // mip level 2087 format, 2088 size.width(), 2089 size.height(), 2090 0, // border 2091 format, 2092 GL_UNSIGNED_BYTE, 2093 zero_data.get()); 2094 2095 size_ = size; 2096 2097 bool success = glGetError() == GL_NO_ERROR; 2098 if (success) { 2099 memory_tracker_.TrackMemFree(bytes_allocated_); 2100 bytes_allocated_ = image_size; 2101 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2102 } 2103 return success; 2104 } 2105 2106 void BackTexture::Copy(const gfx::Size& size, GLenum format) { 2107 DCHECK_NE(id_, 0u); 2108 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", 2109 state_->GetErrorState()); 2110 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 2111 glCopyTexImage2D(GL_TEXTURE_2D, 2112 0, // level 2113 format, 2114 0, 0, 2115 size.width(), 2116 size.height(), 2117 0); // border 2118 } 2119 2120 void BackTexture::Destroy() { 2121 if (id_ != 0) { 2122 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", 2123 state_->GetErrorState()); 2124 glDeleteTextures(1, &id_); 2125 id_ = 0; 2126 } 2127 memory_tracker_.TrackMemFree(bytes_allocated_); 2128 bytes_allocated_ = 0; 2129 } 2130 2131 void BackTexture::Invalidate() { 2132 id_ = 0; 2133 } 2134 2135 BackRenderbuffer::BackRenderbuffer( 2136 RenderbufferManager* renderbuffer_manager, 2137 MemoryTracker* memory_tracker, 2138 ContextState* state) 2139 : renderbuffer_manager_(renderbuffer_manager), 2140 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), 2141 state_(state), 2142 bytes_allocated_(0), 2143 id_(0) { 2144 } 2145 2146 BackRenderbuffer::~BackRenderbuffer() { 2147 // This does not destroy the render buffer because that would require that 2148 // the associated GL context was current. Just check that it was explicitly 2149 // destroyed. 2150 DCHECK_EQ(id_, 0u); 2151 } 2152 2153 void BackRenderbuffer::Create() { 2154 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", 2155 state_->GetErrorState()); 2156 Destroy(); 2157 glGenRenderbuffersEXT(1, &id_); 2158 } 2159 2160 bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info, 2161 const gfx::Size& size, 2162 GLenum format, 2163 GLsizei samples) { 2164 ScopedGLErrorSuppressor suppressor( 2165 "BackRenderbuffer::AllocateStorage", state_->GetErrorState()); 2166 ScopedRenderBufferBinder binder(state_, id_); 2167 2168 uint32 estimated_size = 0; 2169 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize( 2170 size.width(), size.height(), samples, format, &estimated_size)) { 2171 return false; 2172 } 2173 2174 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) { 2175 return false; 2176 } 2177 2178 if (samples <= 1) { 2179 glRenderbufferStorageEXT(GL_RENDERBUFFER, 2180 format, 2181 size.width(), 2182 size.height()); 2183 } else { 2184 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info, 2185 GL_RENDERBUFFER, 2186 samples, 2187 format, 2188 size.width(), 2189 size.height()); 2190 } 2191 bool success = glGetError() == GL_NO_ERROR; 2192 if (success) { 2193 // Mark the previously allocated bytes as free. 2194 memory_tracker_.TrackMemFree(bytes_allocated_); 2195 bytes_allocated_ = estimated_size; 2196 // Track the newly allocated bytes. 2197 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2198 } 2199 return success; 2200 } 2201 2202 void BackRenderbuffer::Destroy() { 2203 if (id_ != 0) { 2204 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", 2205 state_->GetErrorState()); 2206 glDeleteRenderbuffersEXT(1, &id_); 2207 id_ = 0; 2208 } 2209 memory_tracker_.TrackMemFree(bytes_allocated_); 2210 bytes_allocated_ = 0; 2211 } 2212 2213 void BackRenderbuffer::Invalidate() { 2214 id_ = 0; 2215 } 2216 2217 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder) 2218 : decoder_(decoder), 2219 id_(0) { 2220 } 2221 2222 BackFramebuffer::~BackFramebuffer() { 2223 // This does not destroy the frame buffer because that would require that 2224 // the associated GL context was current. Just check that it was explicitly 2225 // destroyed. 2226 DCHECK_EQ(id_, 0u); 2227 } 2228 2229 void BackFramebuffer::Create() { 2230 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", 2231 decoder_->GetErrorState()); 2232 Destroy(); 2233 glGenFramebuffersEXT(1, &id_); 2234 } 2235 2236 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) { 2237 DCHECK_NE(id_, 0u); 2238 ScopedGLErrorSuppressor suppressor( 2239 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState()); 2240 ScopedFrameBufferBinder binder(decoder_, id_); 2241 GLuint attach_id = texture ? texture->id() : 0; 2242 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 2243 GL_COLOR_ATTACHMENT0, 2244 GL_TEXTURE_2D, 2245 attach_id, 2246 0); 2247 } 2248 2249 void BackFramebuffer::AttachRenderBuffer(GLenum target, 2250 BackRenderbuffer* render_buffer) { 2251 DCHECK_NE(id_, 0u); 2252 ScopedGLErrorSuppressor suppressor( 2253 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState()); 2254 ScopedFrameBufferBinder binder(decoder_, id_); 2255 GLuint attach_id = render_buffer ? render_buffer->id() : 0; 2256 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, 2257 target, 2258 GL_RENDERBUFFER, 2259 attach_id); 2260 } 2261 2262 void BackFramebuffer::Destroy() { 2263 if (id_ != 0) { 2264 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", 2265 decoder_->GetErrorState()); 2266 glDeleteFramebuffersEXT(1, &id_); 2267 id_ = 0; 2268 } 2269 } 2270 2271 void BackFramebuffer::Invalidate() { 2272 id_ = 0; 2273 } 2274 2275 GLenum BackFramebuffer::CheckStatus() { 2276 DCHECK_NE(id_, 0u); 2277 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", 2278 decoder_->GetErrorState()); 2279 ScopedFrameBufferBinder binder(decoder_, id_); 2280 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 2281 } 2282 2283 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { 2284 return new GLES2DecoderImpl(group); 2285 } 2286 2287 GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) 2288 : GLES2Decoder(), 2289 group_(group), 2290 logger_(&debug_marker_manager_), 2291 state_(group_->feature_info(), this, &logger_), 2292 unpack_flip_y_(false), 2293 unpack_premultiply_alpha_(false), 2294 unpack_unpremultiply_alpha_(false), 2295 attrib_0_buffer_id_(0), 2296 attrib_0_buffer_matches_value_(true), 2297 attrib_0_size_(0), 2298 fixed_attrib_buffer_id_(0), 2299 fixed_attrib_buffer_size_(0), 2300 offscreen_target_color_format_(0), 2301 offscreen_target_depth_format_(0), 2302 offscreen_target_stencil_format_(0), 2303 offscreen_target_samples_(0), 2304 offscreen_target_buffer_preserved_(true), 2305 offscreen_saved_color_format_(0), 2306 back_buffer_color_format_(0), 2307 back_buffer_has_depth_(false), 2308 back_buffer_has_stencil_(false), 2309 surfaceless_(false), 2310 backbuffer_needs_clear_bits_(0), 2311 current_decoder_error_(error::kNoError), 2312 use_shader_translator_(true), 2313 validators_(group_->feature_info()->validators()), 2314 feature_info_(group_->feature_info()), 2315 frame_number_(0), 2316 has_robustness_extension_(false), 2317 reset_status_(GL_NO_ERROR), 2318 reset_by_robustness_extension_(false), 2319 supports_post_sub_buffer_(false), 2320 force_webgl_glsl_validation_(false), 2321 derivatives_explicitly_enabled_(false), 2322 frag_depth_explicitly_enabled_(false), 2323 draw_buffers_explicitly_enabled_(false), 2324 shader_texture_lod_explicitly_enabled_(false), 2325 compile_shader_always_succeeds_(false), 2326 lose_context_when_out_of_memory_(false), 2327 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( 2328 switches::kEnableGPUServiceLoggingGPU)), 2329 viewport_max_width_(0), 2330 viewport_max_height_(0), 2331 texture_state_(group_->feature_info() 2332 ->workarounds() 2333 .texsubimage2d_faster_than_teximage2d), 2334 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( 2335 TRACE_DISABLED_BY_DEFAULT("cb_command"))), 2336 gpu_trace_level_(2), 2337 gpu_trace_commands_(false), 2338 gpu_debug_commands_(false), 2339 validation_texture_(0), 2340 validation_fbo_multisample_(0), 2341 validation_fbo_(0) { 2342 DCHECK(group); 2343 2344 attrib_0_value_.v[0] = 0.0f; 2345 attrib_0_value_.v[1] = 0.0f; 2346 attrib_0_value_.v[2] = 0.0f; 2347 attrib_0_value_.v[3] = 1.0f; 2348 2349 // The shader translator is used for WebGL even when running on EGL 2350 // because additional restrictions are needed (like only enabling 2351 // GL_OES_standard_derivatives on demand). It is used for the unit 2352 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes 2353 // the empty string to CompileShader and this is not a valid shader. 2354 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL || 2355 CommandLine::ForCurrentProcess()->HasSwitch( 2356 switches::kDisableGLSLTranslator)) { 2357 use_shader_translator_ = false; 2358 } 2359 } 2360 2361 GLES2DecoderImpl::~GLES2DecoderImpl() { 2362 } 2363 2364 bool GLES2DecoderImpl::Initialize( 2365 const scoped_refptr<gfx::GLSurface>& surface, 2366 const scoped_refptr<gfx::GLContext>& context, 2367 bool offscreen, 2368 const gfx::Size& size, 2369 const DisallowedFeatures& disallowed_features, 2370 const std::vector<int32>& attribs) { 2371 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); 2372 DCHECK(context->IsCurrent(surface.get())); 2373 DCHECK(!context_.get()); 2374 2375 surfaceless_ = surface->IsSurfaceless(); 2376 2377 set_initialized(); 2378 gpu_tracer_.reset(new GPUTracer(this)); 2379 gpu_state_tracer_ = GPUStateTracer::Create(&state_); 2380 2381 if (CommandLine::ForCurrentProcess()->HasSwitch( 2382 switches::kEnableGPUDebugging)) { 2383 set_debug(true); 2384 } 2385 2386 if (CommandLine::ForCurrentProcess()->HasSwitch( 2387 switches::kEnableGPUCommandLogging)) { 2388 set_log_commands(true); 2389 } 2390 2391 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( 2392 switches::kCompileShaderAlwaysSucceeds); 2393 2394 2395 // Take ownership of the context and surface. The surface can be replaced with 2396 // SetSurface. 2397 context_ = context; 2398 surface_ = surface; 2399 2400 ContextCreationAttribHelper attrib_parser; 2401 if (!attrib_parser.Parse(attribs)) 2402 return false; 2403 2404 // Save the loseContextWhenOutOfMemory context creation attribute. 2405 lose_context_when_out_of_memory_ = 2406 attrib_parser.lose_context_when_out_of_memory; 2407 2408 // If the failIfMajorPerformanceCaveat context creation attribute was true 2409 // and we are using a software renderer, fail. 2410 if (attrib_parser.fail_if_major_perf_caveat && 2411 feature_info_->feature_flags().is_swiftshader) { 2412 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2413 Destroy(true); 2414 return false; 2415 } 2416 2417 if (!group_->Initialize(this, disallowed_features)) { 2418 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " 2419 << "failed to initialize."; 2420 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2421 Destroy(true); 2422 return false; 2423 } 2424 CHECK_GL_ERROR(); 2425 2426 disallowed_features_ = disallowed_features; 2427 2428 state_.attrib_values.resize(group_->max_vertex_attribs()); 2429 vertex_array_manager_.reset(new VertexArrayManager()); 2430 2431 GLuint default_vertex_attrib_service_id = 0; 2432 if (features().native_vertex_array_object) { 2433 glGenVertexArraysOES(1, &default_vertex_attrib_service_id); 2434 glBindVertexArrayOES(default_vertex_attrib_service_id); 2435 } 2436 2437 state_.default_vertex_attrib_manager = 2438 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false); 2439 2440 state_.default_vertex_attrib_manager->Initialize( 2441 group_->max_vertex_attribs(), 2442 feature_info_->workarounds().init_vertex_attributes); 2443 2444 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call 2445 DoBindVertexArrayOES(0); 2446 2447 query_manager_.reset(new QueryManager(this, feature_info_.get())); 2448 2449 image_manager_.reset(new ImageManager); 2450 2451 util_.set_num_compressed_texture_formats( 2452 validators_->compressed_texture_format.GetValues().size()); 2453 2454 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2455 // We have to enable vertex array 0 on OpenGL or it won't render. Note that 2456 // OpenGL ES 2.0 does not have this issue. 2457 glEnableVertexAttribArray(0); 2458 } 2459 glGenBuffersARB(1, &attrib_0_buffer_id_); 2460 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 2461 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); 2462 glBindBuffer(GL_ARRAY_BUFFER, 0); 2463 glGenBuffersARB(1, &fixed_attrib_buffer_id_); 2464 2465 state_.texture_units.resize(group_->max_texture_units()); 2466 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) { 2467 glActiveTexture(GL_TEXTURE0 + tt); 2468 // We want the last bind to be 2D. 2469 TextureRef* ref; 2470 if (features().oes_egl_image_external) { 2471 ref = texture_manager()->GetDefaultTextureInfo( 2472 GL_TEXTURE_EXTERNAL_OES); 2473 state_.texture_units[tt].bound_texture_external_oes = ref; 2474 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0); 2475 } 2476 if (features().arb_texture_rectangle) { 2477 ref = texture_manager()->GetDefaultTextureInfo( 2478 GL_TEXTURE_RECTANGLE_ARB); 2479 state_.texture_units[tt].bound_texture_rectangle_arb = ref; 2480 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0); 2481 } 2482 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); 2483 state_.texture_units[tt].bound_texture_cube_map = ref; 2484 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); 2485 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); 2486 state_.texture_units[tt].bound_texture_2d = ref; 2487 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); 2488 } 2489 glActiveTexture(GL_TEXTURE0); 2490 CHECK_GL_ERROR(); 2491 2492 if (offscreen) { 2493 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 && 2494 features().chromium_framebuffer_multisample) { 2495 // Per ext_framebuffer_multisample spec, need max bound on sample count. 2496 // max_sample_count must be initialized to a sane value. If 2497 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. 2498 GLint max_sample_count = 1; 2499 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); 2500 offscreen_target_samples_ = std::min(attrib_parser.samples, 2501 max_sample_count); 2502 } else { 2503 offscreen_target_samples_ = 1; 2504 } 2505 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved; 2506 2507 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 2508 const bool rgb8_supported = 2509 context_->HasExtension("GL_OES_rgb8_rgba8"); 2510 // The only available default render buffer formats in GLES2 have very 2511 // little precision. Don't enable multisampling unless 8-bit render 2512 // buffer formats are available--instead fall back to 8-bit textures. 2513 if (rgb8_supported && offscreen_target_samples_ > 1) { 2514 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ? 2515 GL_RGBA8 : GL_RGB8; 2516 } else { 2517 offscreen_target_samples_ = 1; 2518 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ? 2519 GL_RGBA : GL_RGB; 2520 } 2521 2522 // ANGLE only supports packed depth/stencil formats, so use it if it is 2523 // available. 2524 const bool depth24_stencil8_supported = 2525 feature_info_->feature_flags().packed_depth24_stencil8; 2526 VLOG(1) << "GL_OES_packed_depth_stencil " 2527 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2528 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) && 2529 depth24_stencil8_supported) { 2530 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2531 offscreen_target_stencil_format_ = 0; 2532 } else { 2533 // It may be the case that this depth/stencil combination is not 2534 // supported, but this will be checked later by CheckFramebufferStatus. 2535 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ? 2536 GL_DEPTH_COMPONENT16 : 0; 2537 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ? 2538 GL_STENCIL_INDEX8 : 0; 2539 } 2540 } else { 2541 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ? 2542 GL_RGBA : GL_RGB; 2543 2544 // If depth is requested at all, use the packed depth stencil format if 2545 // it's available, as some desktop GL drivers don't support any non-packed 2546 // formats for depth attachments. 2547 const bool depth24_stencil8_supported = 2548 feature_info_->feature_flags().packed_depth24_stencil8; 2549 VLOG(1) << "GL_EXT_packed_depth_stencil " 2550 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2551 2552 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) && 2553 depth24_stencil8_supported) { 2554 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2555 offscreen_target_stencil_format_ = 0; 2556 } else { 2557 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ? 2558 GL_DEPTH_COMPONENT : 0; 2559 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ? 2560 GL_STENCIL_INDEX : 0; 2561 } 2562 } 2563 2564 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ? 2565 GL_RGBA : GL_RGB; 2566 2567 // Create the target frame buffer. This is the one that the client renders 2568 // directly to. 2569 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this)); 2570 offscreen_target_frame_buffer_->Create(); 2571 // Due to GLES2 format limitations, either the color texture (for 2572 // non-multisampling) or the color render buffer (for multisampling) will be 2573 // attached to the offscreen frame buffer. The render buffer has more 2574 // limited formats available to it, but the texture can't do multisampling. 2575 if (IsOffscreenBufferMultisampled()) { 2576 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer( 2577 renderbuffer_manager(), memory_tracker(), &state_)); 2578 offscreen_target_color_render_buffer_->Create(); 2579 } else { 2580 offscreen_target_color_texture_.reset(new BackTexture( 2581 memory_tracker(), &state_)); 2582 offscreen_target_color_texture_->Create(); 2583 } 2584 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer( 2585 renderbuffer_manager(), memory_tracker(), &state_)); 2586 offscreen_target_depth_render_buffer_->Create(); 2587 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer( 2588 renderbuffer_manager(), memory_tracker(), &state_)); 2589 offscreen_target_stencil_render_buffer_->Create(); 2590 2591 // Create the saved offscreen texture. The target frame buffer is copied 2592 // here when SwapBuffers is called. 2593 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this)); 2594 offscreen_saved_frame_buffer_->Create(); 2595 // 2596 offscreen_saved_color_texture_.reset(new BackTexture( 2597 memory_tracker(), &state_)); 2598 offscreen_saved_color_texture_->Create(); 2599 2600 // Allocate the render buffers at their initial size and check the status 2601 // of the frame buffers is okay. 2602 if (!ResizeOffscreenFrameBuffer(size)) { 2603 LOG(ERROR) << "Could not allocate offscreen buffer storage."; 2604 Destroy(true); 2605 return false; 2606 } 2607 2608 // Allocate the offscreen saved color texture. 2609 DCHECK(offscreen_saved_color_format_); 2610 offscreen_saved_color_texture_->AllocateStorage( 2611 gfx::Size(1, 1), offscreen_saved_color_format_, true); 2612 2613 offscreen_saved_frame_buffer_->AttachRenderTexture( 2614 offscreen_saved_color_texture_.get()); 2615 if (offscreen_saved_frame_buffer_->CheckStatus() != 2616 GL_FRAMEBUFFER_COMPLETE) { 2617 LOG(ERROR) << "Offscreen saved FBO was incomplete."; 2618 Destroy(true); 2619 return false; 2620 } 2621 2622 // Bind to the new default frame buffer (the offscreen target frame buffer). 2623 // This should now be associated with ID zero. 2624 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2625 } else { 2626 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); 2627 // These are NOT if the back buffer has these proprorties. They are 2628 // if we want the command buffer to enforce them regardless of what 2629 // the real backbuffer is assuming the real back buffer gives us more than 2630 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll 2631 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we 2632 // can't do anything about that. 2633 2634 if (!surfaceless_) { 2635 GLint v = 0; 2636 glGetIntegerv(GL_ALPHA_BITS, &v); 2637 // This checks if the user requested RGBA and we have RGBA then RGBA. If 2638 // the user requested RGB then RGB. If the user did not specify a 2639 // preference than use whatever we were given. Same for DEPTH and STENCIL. 2640 back_buffer_color_format_ = 2641 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB; 2642 glGetIntegerv(GL_DEPTH_BITS, &v); 2643 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0; 2644 glGetIntegerv(GL_STENCIL_BITS, &v); 2645 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0; 2646 } 2647 } 2648 2649 // OpenGL ES 2.0 implicitly enables the desktop GL capability 2650 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact 2651 // isn't well documented; it was discovered in the Khronos OpenGL ES 2652 // mailing list archives. It also implicitly enables the desktop GL 2653 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord 2654 // variable in fragment shaders. 2655 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2656 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); 2657 glEnable(GL_POINT_SPRITE); 2658 } 2659 2660 has_robustness_extension_ = 2661 context->HasExtension("GL_ARB_robustness") || 2662 context->HasExtension("GL_EXT_robustness"); 2663 2664 if (!InitializeShaderTranslator()) { 2665 return false; 2666 } 2667 2668 state_.viewport_width = size.width(); 2669 state_.viewport_height = size.height(); 2670 2671 GLint viewport_params[4] = { 0 }; 2672 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); 2673 viewport_max_width_ = viewport_params[0]; 2674 viewport_max_height_ = viewport_params[1]; 2675 2676 state_.scissor_width = state_.viewport_width; 2677 state_.scissor_height = state_.viewport_height; 2678 2679 // Set all the default state because some GL drivers get it wrong. 2680 state_.InitCapabilities(NULL); 2681 state_.InitState(NULL); 2682 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2683 2684 DoBindBuffer(GL_ARRAY_BUFFER, 0); 2685 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2686 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2687 DoBindRenderbuffer(GL_RENDERBUFFER, 0); 2688 2689 bool call_gl_clear = !surfaceless_; 2690 #if defined(OS_ANDROID) 2691 // Temporary workaround for Android WebView because this clear ignores the 2692 // clip and corrupts that external UI of the App. Not calling glClear is ok 2693 // because the system already clears the buffer before each draw. Proper 2694 // fix might be setting the scissor clip properly before initialize. See 2695 // crbug.com/259023 for details. 2696 call_gl_clear = surface_->GetHandle(); 2697 #endif 2698 if (call_gl_clear) { 2699 // Clear the backbuffer. 2700 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2701 } 2702 2703 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer(); 2704 if (feature_info_->workarounds() 2705 .disable_post_sub_buffers_for_onscreen_surfaces && 2706 !surface->IsOffscreen()) 2707 supports_post_sub_buffer_ = false; 2708 2709 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { 2710 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 2711 } 2712 2713 if (feature_info_->workarounds().unbind_fbo_on_context_switch) { 2714 context_->SetUnbindFboOnMakeCurrent(); 2715 } 2716 2717 // Only compositor contexts are known to use only the subset of GL 2718 // that can be safely migrated between the iGPU and the dGPU. Mark 2719 // those contexts as safe to forcibly transition between the GPUs. 2720 // http://crbug.com/180876, http://crbug.com/227228 2721 if (!offscreen) 2722 context_->SetSafeToForceGpuSwitch(); 2723 2724 async_pixel_transfer_manager_.reset( 2725 AsyncPixelTransferManager::Create(context.get())); 2726 async_pixel_transfer_manager_->Initialize(texture_manager()); 2727 2728 framebuffer_manager()->AddObserver(this); 2729 2730 return true; 2731 } 2732 2733 Capabilities GLES2DecoderImpl::GetCapabilities() { 2734 DCHECK(initialized()); 2735 2736 Capabilities caps; 2737 2738 caps.egl_image_external = 2739 feature_info_->feature_flags().oes_egl_image_external; 2740 caps.texture_format_bgra8888 = 2741 feature_info_->feature_flags().ext_texture_format_bgra8888; 2742 caps.texture_format_etc1 = 2743 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; 2744 caps.texture_format_etc1_npot = 2745 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only; 2746 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle; 2747 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage; 2748 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage; 2749 caps.discard_framebuffer = 2750 feature_info_->feature_flags().ext_discard_framebuffer; 2751 caps.sync_query = feature_info_->feature_flags().chromium_sync_query; 2752 2753 #if defined(OS_MACOSX) 2754 // This is unconditionally true on mac, no need to test for it at runtime. 2755 caps.iosurface = true; 2756 #endif 2757 2758 caps.post_sub_buffer = supports_post_sub_buffer_; 2759 caps.map_image = true; 2760 2761 return caps; 2762 } 2763 2764 void GLES2DecoderImpl::UpdateCapabilities() { 2765 util_.set_num_compressed_texture_formats( 2766 validators_->compressed_texture_format.GetValues().size()); 2767 util_.set_num_shader_binary_formats( 2768 validators_->shader_binary_format.GetValues().size()); 2769 } 2770 2771 bool GLES2DecoderImpl::InitializeShaderTranslator() { 2772 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator"); 2773 2774 if (!use_shader_translator_) { 2775 return true; 2776 } 2777 ShBuiltInResources resources; 2778 ShInitBuiltInResources(&resources); 2779 resources.MaxVertexAttribs = group_->max_vertex_attribs(); 2780 resources.MaxVertexUniformVectors = 2781 group_->max_vertex_uniform_vectors(); 2782 resources.MaxVaryingVectors = group_->max_varying_vectors(); 2783 resources.MaxVertexTextureImageUnits = 2784 group_->max_vertex_texture_image_units(); 2785 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); 2786 resources.MaxTextureImageUnits = group_->max_texture_image_units(); 2787 resources.MaxFragmentUniformVectors = 2788 group_->max_fragment_uniform_vectors(); 2789 resources.MaxDrawBuffers = group_->max_draw_buffers(); 2790 resources.MaxExpressionComplexity = 256; 2791 resources.MaxCallStackDepth = 256; 2792 2793 GLint range[2] = { 0, 0 }; 2794 GLint precision = 0; 2795 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, 2796 range, &precision); 2797 resources.FragmentPrecisionHigh = 2798 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision); 2799 2800 if (force_webgl_glsl_validation_) { 2801 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; 2802 resources.EXT_frag_depth = frag_depth_explicitly_enabled_; 2803 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_; 2804 if (!draw_buffers_explicitly_enabled_) 2805 resources.MaxDrawBuffers = 1; 2806 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_; 2807 } else { 2808 resources.OES_standard_derivatives = 2809 features().oes_standard_derivatives ? 1 : 0; 2810 resources.ARB_texture_rectangle = 2811 features().arb_texture_rectangle ? 1 : 0; 2812 resources.OES_EGL_image_external = 2813 features().oes_egl_image_external ? 1 : 0; 2814 resources.EXT_draw_buffers = 2815 features().ext_draw_buffers ? 1 : 0; 2816 resources.EXT_frag_depth = 2817 features().ext_frag_depth ? 1 : 0; 2818 resources.EXT_shader_texture_lod = 2819 features().ext_shader_texture_lod ? 1 : 0; 2820 } 2821 2822 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC 2823 : SH_GLES2_SPEC; 2824 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing) 2825 resources.HashFunction = &CityHash64; 2826 else 2827 resources.HashFunction = NULL; 2828 ShaderTranslatorInterface::GlslImplementationType implementation_type = 2829 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ? 2830 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl; 2831 int driver_bug_workarounds = 0; 2832 if (workarounds().needs_glsl_built_in_function_emulation) 2833 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS; 2834 if (workarounds().init_gl_position_in_vertex_shader) 2835 driver_bug_workarounds |= SH_INIT_GL_POSITION; 2836 if (workarounds().unfold_short_circuit_as_ternary_operation) 2837 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT; 2838 if (workarounds().init_varyings_without_static_use) 2839 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE; 2840 if (workarounds().unroll_for_loop_with_sampler_array_index) 2841 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX; 2842 if (workarounds().scalarize_vec_and_mat_constructor_args) 2843 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS; 2844 if (workarounds().regenerate_struct_names) 2845 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES; 2846 2847 vertex_translator_ = shader_translator_cache()->GetTranslator( 2848 GL_VERTEX_SHADER, 2849 shader_spec, 2850 &resources, 2851 implementation_type, 2852 static_cast<ShCompileOptions>(driver_bug_workarounds)); 2853 if (!vertex_translator_.get()) { 2854 LOG(ERROR) << "Could not initialize vertex shader translator."; 2855 Destroy(true); 2856 return false; 2857 } 2858 2859 fragment_translator_ = shader_translator_cache()->GetTranslator( 2860 GL_FRAGMENT_SHADER, 2861 shader_spec, 2862 &resources, 2863 implementation_type, 2864 static_cast<ShCompileOptions>(driver_bug_workarounds)); 2865 if (!fragment_translator_.get()) { 2866 LOG(ERROR) << "Could not initialize fragment shader translator."; 2867 Destroy(true); 2868 return false; 2869 } 2870 return true; 2871 } 2872 2873 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) { 2874 for (GLsizei ii = 0; ii < n; ++ii) { 2875 if (GetBuffer(client_ids[ii])) { 2876 return false; 2877 } 2878 } 2879 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2880 glGenBuffersARB(n, service_ids.get()); 2881 for (GLsizei ii = 0; ii < n; ++ii) { 2882 CreateBuffer(client_ids[ii], service_ids[ii]); 2883 } 2884 return true; 2885 } 2886 2887 bool GLES2DecoderImpl::GenFramebuffersHelper( 2888 GLsizei n, const GLuint* client_ids) { 2889 for (GLsizei ii = 0; ii < n; ++ii) { 2890 if (GetFramebuffer(client_ids[ii])) { 2891 return false; 2892 } 2893 } 2894 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2895 glGenFramebuffersEXT(n, service_ids.get()); 2896 for (GLsizei ii = 0; ii < n; ++ii) { 2897 CreateFramebuffer(client_ids[ii], service_ids[ii]); 2898 } 2899 return true; 2900 } 2901 2902 bool GLES2DecoderImpl::GenRenderbuffersHelper( 2903 GLsizei n, const GLuint* client_ids) { 2904 for (GLsizei ii = 0; ii < n; ++ii) { 2905 if (GetRenderbuffer(client_ids[ii])) { 2906 return false; 2907 } 2908 } 2909 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2910 glGenRenderbuffersEXT(n, service_ids.get()); 2911 for (GLsizei ii = 0; ii < n; ++ii) { 2912 CreateRenderbuffer(client_ids[ii], service_ids[ii]); 2913 } 2914 return true; 2915 } 2916 2917 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { 2918 for (GLsizei ii = 0; ii < n; ++ii) { 2919 if (GetTexture(client_ids[ii])) { 2920 return false; 2921 } 2922 } 2923 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2924 glGenTextures(n, service_ids.get()); 2925 for (GLsizei ii = 0; ii < n; ++ii) { 2926 CreateTexture(client_ids[ii], service_ids[ii]); 2927 } 2928 return true; 2929 } 2930 2931 void GLES2DecoderImpl::DeleteBuffersHelper( 2932 GLsizei n, const GLuint* client_ids) { 2933 for (GLsizei ii = 0; ii < n; ++ii) { 2934 Buffer* buffer = GetBuffer(client_ids[ii]); 2935 if (buffer && !buffer->IsDeleted()) { 2936 state_.vertex_attrib_manager->Unbind(buffer); 2937 if (state_.bound_array_buffer.get() == buffer) { 2938 state_.bound_array_buffer = NULL; 2939 } 2940 RemoveBuffer(client_ids[ii]); 2941 } 2942 } 2943 } 2944 2945 void GLES2DecoderImpl::DeleteFramebuffersHelper( 2946 GLsizei n, const GLuint* client_ids) { 2947 bool supports_separate_framebuffer_binds = 2948 features().chromium_framebuffer_multisample; 2949 2950 for (GLsizei ii = 0; ii < n; ++ii) { 2951 Framebuffer* framebuffer = 2952 GetFramebuffer(client_ids[ii]); 2953 if (framebuffer && !framebuffer->IsDeleted()) { 2954 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 2955 framebuffer_state_.bound_draw_framebuffer = NULL; 2956 framebuffer_state_.clear_state_dirty = true; 2957 GLenum target = supports_separate_framebuffer_binds ? 2958 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2959 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2960 } 2961 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) { 2962 framebuffer_state_.bound_read_framebuffer = NULL; 2963 GLenum target = supports_separate_framebuffer_binds ? 2964 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2965 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2966 } 2967 OnFboChanged(); 2968 RemoveFramebuffer(client_ids[ii]); 2969 } 2970 } 2971 } 2972 2973 void GLES2DecoderImpl::DeleteRenderbuffersHelper( 2974 GLsizei n, const GLuint* client_ids) { 2975 bool supports_separate_framebuffer_binds = 2976 features().chromium_framebuffer_multisample; 2977 for (GLsizei ii = 0; ii < n; ++ii) { 2978 Renderbuffer* renderbuffer = 2979 GetRenderbuffer(client_ids[ii]); 2980 if (renderbuffer && !renderbuffer->IsDeleted()) { 2981 if (state_.bound_renderbuffer.get() == renderbuffer) { 2982 state_.bound_renderbuffer = NULL; 2983 } 2984 // Unbind from current framebuffers. 2985 if (supports_separate_framebuffer_binds) { 2986 if (framebuffer_state_.bound_read_framebuffer.get()) { 2987 framebuffer_state_.bound_read_framebuffer 2988 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer); 2989 } 2990 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2991 framebuffer_state_.bound_draw_framebuffer 2992 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); 2993 } 2994 } else { 2995 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2996 framebuffer_state_.bound_draw_framebuffer 2997 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer); 2998 } 2999 } 3000 framebuffer_state_.clear_state_dirty = true; 3001 RemoveRenderbuffer(client_ids[ii]); 3002 } 3003 } 3004 } 3005 3006 void GLES2DecoderImpl::DeleteTexturesHelper( 3007 GLsizei n, const GLuint* client_ids) { 3008 bool supports_separate_framebuffer_binds = 3009 features().chromium_framebuffer_multisample; 3010 for (GLsizei ii = 0; ii < n; ++ii) { 3011 TextureRef* texture_ref = GetTexture(client_ids[ii]); 3012 if (texture_ref) { 3013 Texture* texture = texture_ref->texture(); 3014 if (texture->IsAttachedToFramebuffer()) { 3015 framebuffer_state_.clear_state_dirty = true; 3016 } 3017 // Unbind texture_ref from texture_ref units. 3018 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) { 3019 state_.texture_units[jj].Unbind(texture_ref); 3020 } 3021 // Unbind from current framebuffers. 3022 if (supports_separate_framebuffer_binds) { 3023 if (framebuffer_state_.bound_read_framebuffer.get()) { 3024 framebuffer_state_.bound_read_framebuffer 3025 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); 3026 } 3027 if (framebuffer_state_.bound_draw_framebuffer.get()) { 3028 framebuffer_state_.bound_draw_framebuffer 3029 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); 3030 } 3031 } else { 3032 if (framebuffer_state_.bound_draw_framebuffer.get()) { 3033 framebuffer_state_.bound_draw_framebuffer 3034 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); 3035 } 3036 } 3037 #if defined(OS_MACOSX) 3038 GLuint service_id = texture->service_id(); 3039 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) { 3040 ReleaseIOSurfaceForTexture(service_id); 3041 } 3042 #endif 3043 RemoveTexture(client_ids[ii]); 3044 } 3045 } 3046 } 3047 3048 // } // anonymous namespace 3049 3050 bool GLES2DecoderImpl::MakeCurrent() { 3051 if (!context_.get()) 3052 return false; 3053 3054 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) { 3055 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 3056 3057 // Some D3D drivers cannot recover from device lost in the GPU process 3058 // sandbox. Allow a new GPU process to launch. 3059 if (workarounds().exit_on_context_lost) { 3060 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset" 3061 << " a D3D device in the Chrome GPU process sandbox."; 3062 #if defined(OS_WIN) 3063 base::win::SetShouldCrashOnProcessDetach(false); 3064 #endif 3065 exit(0); 3066 } 3067 3068 return false; 3069 } 3070 3071 ProcessFinishedAsyncTransfers(); 3072 3073 // Rebind the FBO if it was unbound by the context. 3074 if (workarounds().unbind_fbo_on_context_switch) 3075 RestoreFramebufferBindings(); 3076 3077 framebuffer_state_.clear_state_dirty = true; 3078 3079 return true; 3080 } 3081 3082 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { 3083 ProcessPendingReadPixels(); 3084 if (engine() && query_manager_.get()) 3085 query_manager_->ProcessPendingTransferQueries(); 3086 3087 // TODO(epenner): Is there a better place to do this? 3088 // This needs to occur before we execute any batch of commands 3089 // from the client, as the client may have recieved an async 3090 // completion while issuing those commands. 3091 // "DidFlushStart" would be ideal if we had such a callback. 3092 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); 3093 } 3094 3095 static void RebindCurrentFramebuffer( 3096 GLenum target, 3097 Framebuffer* framebuffer, 3098 GLuint back_buffer_service_id) { 3099 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0; 3100 3101 if (framebuffer_id == 0) { 3102 framebuffer_id = back_buffer_service_id; 3103 } 3104 3105 glBindFramebufferEXT(target, framebuffer_id); 3106 } 3107 3108 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { 3109 framebuffer_state_.clear_state_dirty = true; 3110 3111 if (!features().chromium_framebuffer_multisample) { 3112 RebindCurrentFramebuffer( 3113 GL_FRAMEBUFFER, 3114 framebuffer_state_.bound_draw_framebuffer.get(), 3115 GetBackbufferServiceId()); 3116 } else { 3117 RebindCurrentFramebuffer( 3118 GL_READ_FRAMEBUFFER_EXT, 3119 framebuffer_state_.bound_read_framebuffer.get(), 3120 GetBackbufferServiceId()); 3121 RebindCurrentFramebuffer( 3122 GL_DRAW_FRAMEBUFFER_EXT, 3123 framebuffer_state_.bound_draw_framebuffer.get(), 3124 GetBackbufferServiceId()); 3125 } 3126 OnFboChanged(); 3127 } 3128 3129 bool GLES2DecoderImpl::CheckFramebufferValid( 3130 Framebuffer* framebuffer, 3131 GLenum target, const char* func_name) { 3132 if (!framebuffer) { 3133 if (surfaceless_) 3134 return false; 3135 if (backbuffer_needs_clear_bits_) { 3136 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3137 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3138 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3139 glClearStencil(0); 3140 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); 3141 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); 3142 glClearDepth(1.0f); 3143 state_.SetDeviceDepthMask(GL_TRUE); 3144 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 3145 bool reset_draw_buffer = false; 3146 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 && 3147 group_->draw_buffer() == GL_NONE) { 3148 reset_draw_buffer = true; 3149 GLenum buf = GL_BACK; 3150 if (GetBackbufferServiceId() != 0) // emulated backbuffer 3151 buf = GL_COLOR_ATTACHMENT0; 3152 glDrawBuffersARB(1, &buf); 3153 } 3154 glClear(backbuffer_needs_clear_bits_); 3155 if (reset_draw_buffer) { 3156 GLenum buf = GL_NONE; 3157 glDrawBuffersARB(1, &buf); 3158 } 3159 backbuffer_needs_clear_bits_ = 0; 3160 RestoreClearState(); 3161 } 3162 return true; 3163 } 3164 3165 if (framebuffer_manager()->IsComplete(framebuffer)) { 3166 return true; 3167 } 3168 3169 GLenum completeness = framebuffer->IsPossiblyComplete(); 3170 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 3171 LOCAL_SET_GL_ERROR( 3172 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); 3173 return false; 3174 } 3175 3176 // Are all the attachments cleared? 3177 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || 3178 texture_manager()->HaveUnclearedMips()) { 3179 if (!framebuffer->IsCleared()) { 3180 // Can we clear them? 3181 if (framebuffer->GetStatus(texture_manager(), target) != 3182 GL_FRAMEBUFFER_COMPLETE) { 3183 LOCAL_SET_GL_ERROR( 3184 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 3185 "framebuffer incomplete (clear)"); 3186 return false; 3187 } 3188 ClearUnclearedAttachments(target, framebuffer); 3189 } 3190 } 3191 3192 if (!framebuffer_manager()->IsComplete(framebuffer)) { 3193 if (framebuffer->GetStatus(texture_manager(), target) != 3194 GL_FRAMEBUFFER_COMPLETE) { 3195 LOCAL_SET_GL_ERROR( 3196 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 3197 "framebuffer incomplete (check)"); 3198 return false; 3199 } 3200 framebuffer_manager()->MarkAsComplete(framebuffer); 3201 } 3202 3203 // NOTE: At this point we don't know if the framebuffer is complete but 3204 // we DO know that everything that needs to be cleared has been cleared. 3205 return true; 3206 } 3207 3208 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) { 3209 if (!features().chromium_framebuffer_multisample) { 3210 bool valid = CheckFramebufferValid( 3211 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, 3212 func_name); 3213 3214 if (valid) 3215 OnUseFramebuffer(); 3216 3217 return valid; 3218 } 3219 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(), 3220 GL_DRAW_FRAMEBUFFER_EXT, 3221 func_name) && 3222 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(), 3223 GL_READ_FRAMEBUFFER_EXT, 3224 func_name); 3225 } 3226 3227 bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment( 3228 const char* func_name) { 3229 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ? 3230 framebuffer_state_.bound_read_framebuffer.get() : 3231 framebuffer_state_.bound_draw_framebuffer.get(); 3232 if (!framebuffer) 3233 return true; 3234 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) { 3235 LOCAL_SET_GL_ERROR( 3236 GL_INVALID_OPERATION, func_name, "no color image attached"); 3237 return false; 3238 } 3239 return true; 3240 } 3241 3242 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { 3243 Framebuffer* framebuffer = 3244 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3245 if (framebuffer != NULL) { 3246 const Framebuffer::Attachment* attachment = 3247 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0); 3248 if (attachment) { 3249 return gfx::Size(attachment->width(), attachment->height()); 3250 } 3251 return gfx::Size(0, 0); 3252 } else if (offscreen_target_frame_buffer_.get()) { 3253 return offscreen_size_; 3254 } else { 3255 return surface_->GetSize(); 3256 } 3257 } 3258 3259 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() { 3260 Framebuffer* framebuffer = 3261 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3262 if (framebuffer != NULL) { 3263 return framebuffer->GetColorAttachmentTextureType(); 3264 } else { 3265 return GL_UNSIGNED_BYTE; 3266 } 3267 } 3268 3269 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { 3270 Framebuffer* framebuffer = 3271 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3272 if (framebuffer != NULL) { 3273 return framebuffer->GetColorAttachmentFormat(); 3274 } else if (offscreen_target_frame_buffer_.get()) { 3275 return offscreen_target_color_format_; 3276 } else { 3277 return back_buffer_color_format_; 3278 } 3279 } 3280 3281 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { 3282 Framebuffer* framebuffer = 3283 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3284 if (framebuffer != NULL) { 3285 return framebuffer->GetColorAttachmentFormat(); 3286 } else if (offscreen_target_frame_buffer_.get()) { 3287 return offscreen_target_color_format_; 3288 } else { 3289 return back_buffer_color_format_; 3290 } 3291 } 3292 3293 void GLES2DecoderImpl::UpdateParentTextureInfo() { 3294 if (!offscreen_saved_color_texture_info_.get()) 3295 return; 3296 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); 3297 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); 3298 texture_manager()->SetLevelInfo( 3299 offscreen_saved_color_texture_info_.get(), 3300 GL_TEXTURE_2D, 3301 0, // level 3302 GL_RGBA, 3303 offscreen_size_.width(), 3304 offscreen_size_.height(), 3305 1, // depth 3306 0, // border 3307 GL_RGBA, 3308 GL_UNSIGNED_BYTE, 3309 true); 3310 texture_manager()->SetParameteri( 3311 "UpdateParentTextureInfo", 3312 GetErrorState(), 3313 offscreen_saved_color_texture_info_.get(), 3314 GL_TEXTURE_MAG_FILTER, 3315 GL_LINEAR); 3316 texture_manager()->SetParameteri( 3317 "UpdateParentTextureInfo", 3318 GetErrorState(), 3319 offscreen_saved_color_texture_info_.get(), 3320 GL_TEXTURE_MIN_FILTER, 3321 GL_LINEAR); 3322 texture_manager()->SetParameteri( 3323 "UpdateParentTextureInfo", 3324 GetErrorState(), 3325 offscreen_saved_color_texture_info_.get(), 3326 GL_TEXTURE_WRAP_S, 3327 GL_CLAMP_TO_EDGE); 3328 texture_manager()->SetParameteri( 3329 "UpdateParentTextureInfo", 3330 GetErrorState(), 3331 offscreen_saved_color_texture_info_.get(), 3332 GL_TEXTURE_WRAP_T, 3333 GL_CLAMP_TO_EDGE); 3334 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 3335 &state_, target); 3336 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0); 3337 } 3338 3339 void GLES2DecoderImpl::SetResizeCallback( 3340 const base::Callback<void(gfx::Size, float)>& callback) { 3341 resize_callback_ = callback; 3342 } 3343 3344 Logger* GLES2DecoderImpl::GetLogger() { 3345 return &logger_; 3346 } 3347 3348 void GLES2DecoderImpl::BeginDecoding() { 3349 gpu_tracer_->BeginDecoding(); 3350 gpu_trace_commands_ = gpu_tracer_->IsTracing(); 3351 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ || 3352 (*cb_command_trace_category_ != 0); 3353 } 3354 3355 void GLES2DecoderImpl::EndDecoding() { 3356 gpu_tracer_->EndDecoding(); 3357 } 3358 3359 ErrorState* GLES2DecoderImpl::GetErrorState() { 3360 return state_.GetErrorState(); 3361 } 3362 3363 void GLES2DecoderImpl::SetShaderCacheCallback( 3364 const ShaderCacheCallback& callback) { 3365 shader_cache_callback_ = callback; 3366 } 3367 3368 void GLES2DecoderImpl::SetWaitSyncPointCallback( 3369 const WaitSyncPointCallback& callback) { 3370 wait_sync_point_callback_ = callback; 3371 } 3372 3373 AsyncPixelTransferManager* 3374 GLES2DecoderImpl::GetAsyncPixelTransferManager() { 3375 return async_pixel_transfer_manager_.get(); 3376 } 3377 3378 void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() { 3379 async_pixel_transfer_manager_.reset(); 3380 } 3381 3382 void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest( 3383 AsyncPixelTransferManager* manager) { 3384 async_pixel_transfer_manager_ = make_scoped_ptr(manager); 3385 } 3386 3387 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, 3388 uint32* service_texture_id) { 3389 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id); 3390 if (texture_ref) { 3391 *service_texture_id = texture_ref->service_id(); 3392 return true; 3393 } 3394 return false; 3395 } 3396 3397 uint32 GLES2DecoderImpl::GetTextureUploadCount() { 3398 return texture_state_.texture_upload_count + 3399 async_pixel_transfer_manager_->GetTextureUploadCount(); 3400 } 3401 3402 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { 3403 return texture_state_.total_texture_upload_time + 3404 async_pixel_transfer_manager_->GetTotalTextureUploadTime(); 3405 } 3406 3407 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { 3408 return total_processing_commands_time_; 3409 } 3410 3411 void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) { 3412 total_processing_commands_time_ += time; 3413 } 3414 3415 void GLES2DecoderImpl::Destroy(bool have_context) { 3416 if (!initialized()) 3417 return; 3418 3419 DCHECK(!have_context || context_->IsCurrent(NULL)); 3420 3421 // Unbind everything. 3422 state_.vertex_attrib_manager = NULL; 3423 state_.default_vertex_attrib_manager = NULL; 3424 state_.texture_units.clear(); 3425 state_.bound_array_buffer = NULL; 3426 state_.current_queries.clear(); 3427 framebuffer_state_.bound_read_framebuffer = NULL; 3428 framebuffer_state_.bound_draw_framebuffer = NULL; 3429 state_.bound_renderbuffer = NULL; 3430 3431 if (offscreen_saved_color_texture_info_.get()) { 3432 DCHECK(offscreen_target_color_texture_); 3433 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(), 3434 offscreen_saved_color_texture_->id()); 3435 offscreen_saved_color_texture_->Invalidate(); 3436 offscreen_saved_color_texture_info_ = NULL; 3437 } 3438 if (have_context) { 3439 if (copy_texture_CHROMIUM_.get()) { 3440 copy_texture_CHROMIUM_->Destroy(); 3441 copy_texture_CHROMIUM_.reset(); 3442 } 3443 3444 if (state_.current_program.get()) { 3445 program_manager()->UnuseProgram(shader_manager(), 3446 state_.current_program.get()); 3447 } 3448 3449 if (attrib_0_buffer_id_) { 3450 glDeleteBuffersARB(1, &attrib_0_buffer_id_); 3451 } 3452 if (fixed_attrib_buffer_id_) { 3453 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_); 3454 } 3455 3456 if (validation_texture_) { 3457 glDeleteTextures(1, &validation_texture_); 3458 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_); 3459 glDeleteFramebuffersEXT(1, &validation_fbo_); 3460 } 3461 3462 if (offscreen_target_frame_buffer_.get()) 3463 offscreen_target_frame_buffer_->Destroy(); 3464 if (offscreen_target_color_texture_.get()) 3465 offscreen_target_color_texture_->Destroy(); 3466 if (offscreen_target_color_render_buffer_.get()) 3467 offscreen_target_color_render_buffer_->Destroy(); 3468 if (offscreen_target_depth_render_buffer_.get()) 3469 offscreen_target_depth_render_buffer_->Destroy(); 3470 if (offscreen_target_stencil_render_buffer_.get()) 3471 offscreen_target_stencil_render_buffer_->Destroy(); 3472 if (offscreen_saved_frame_buffer_.get()) 3473 offscreen_saved_frame_buffer_->Destroy(); 3474 if (offscreen_saved_color_texture_.get()) 3475 offscreen_saved_color_texture_->Destroy(); 3476 if (offscreen_resolved_frame_buffer_.get()) 3477 offscreen_resolved_frame_buffer_->Destroy(); 3478 if (offscreen_resolved_color_texture_.get()) 3479 offscreen_resolved_color_texture_->Destroy(); 3480 } else { 3481 if (offscreen_target_frame_buffer_.get()) 3482 offscreen_target_frame_buffer_->Invalidate(); 3483 if (offscreen_target_color_texture_.get()) 3484 offscreen_target_color_texture_->Invalidate(); 3485 if (offscreen_target_color_render_buffer_.get()) 3486 offscreen_target_color_render_buffer_->Invalidate(); 3487 if (offscreen_target_depth_render_buffer_.get()) 3488 offscreen_target_depth_render_buffer_->Invalidate(); 3489 if (offscreen_target_stencil_render_buffer_.get()) 3490 offscreen_target_stencil_render_buffer_->Invalidate(); 3491 if (offscreen_saved_frame_buffer_.get()) 3492 offscreen_saved_frame_buffer_->Invalidate(); 3493 if (offscreen_saved_color_texture_.get()) 3494 offscreen_saved_color_texture_->Invalidate(); 3495 if (offscreen_resolved_frame_buffer_.get()) 3496 offscreen_resolved_frame_buffer_->Invalidate(); 3497 if (offscreen_resolved_color_texture_.get()) 3498 offscreen_resolved_color_texture_->Invalidate(); 3499 } 3500 3501 // Current program must be cleared after calling ProgramManager::UnuseProgram. 3502 // Otherwise, we can leak objects. http://crbug.com/258772. 3503 // state_.current_program must be reset before group_ is reset because 3504 // the later deletes the ProgramManager object that referred by 3505 // state_.current_program object. 3506 state_.current_program = NULL; 3507 3508 copy_texture_CHROMIUM_.reset(); 3509 3510 if (query_manager_.get()) { 3511 query_manager_->Destroy(have_context); 3512 query_manager_.reset(); 3513 } 3514 3515 if (vertex_array_manager_ .get()) { 3516 vertex_array_manager_->Destroy(have_context); 3517 vertex_array_manager_.reset(); 3518 } 3519 3520 if (image_manager_.get()) { 3521 image_manager_->Destroy(have_context); 3522 image_manager_.reset(); 3523 } 3524 3525 offscreen_target_frame_buffer_.reset(); 3526 offscreen_target_color_texture_.reset(); 3527 offscreen_target_color_render_buffer_.reset(); 3528 offscreen_target_depth_render_buffer_.reset(); 3529 offscreen_target_stencil_render_buffer_.reset(); 3530 offscreen_saved_frame_buffer_.reset(); 3531 offscreen_saved_color_texture_.reset(); 3532 offscreen_resolved_frame_buffer_.reset(); 3533 offscreen_resolved_color_texture_.reset(); 3534 3535 // Need to release these before releasing |group_| which may own the 3536 // ShaderTranslatorCache. 3537 fragment_translator_ = NULL; 3538 vertex_translator_ = NULL; 3539 3540 // Should destroy the transfer manager before the texture manager held 3541 // by the context group. 3542 async_pixel_transfer_manager_.reset(); 3543 3544 if (group_.get()) { 3545 framebuffer_manager()->RemoveObserver(this); 3546 group_->Destroy(this, have_context); 3547 group_ = NULL; 3548 } 3549 3550 if (context_.get()) { 3551 context_->ReleaseCurrent(NULL); 3552 context_ = NULL; 3553 } 3554 3555 #if defined(OS_MACOSX) 3556 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin(); 3557 it != texture_to_io_surface_map_.end(); ++it) { 3558 CFRelease(it->second); 3559 } 3560 texture_to_io_surface_map_.clear(); 3561 #endif 3562 } 3563 3564 void GLES2DecoderImpl::SetSurface( 3565 const scoped_refptr<gfx::GLSurface>& surface) { 3566 DCHECK(context_->IsCurrent(NULL)); 3567 DCHECK(surface_.get()); 3568 surface_ = surface; 3569 RestoreCurrentFramebufferBindings(); 3570 } 3571 3572 void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) { 3573 if (!offscreen_saved_color_texture_.get()) { 3574 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context"; 3575 return; 3576 } 3577 if (!offscreen_saved_color_texture_info_.get()) { 3578 GLuint service_id = offscreen_saved_color_texture_->id(); 3579 offscreen_saved_color_texture_info_ = TextureRef::Create( 3580 texture_manager(), 0, service_id); 3581 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(), 3582 GL_TEXTURE_2D); 3583 UpdateParentTextureInfo(); 3584 } 3585 mailbox_manager()->ProduceTexture( 3586 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture()); 3587 } 3588 3589 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { 3590 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3591 if (!is_offscreen) { 3592 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " 3593 << " with an onscreen framebuffer."; 3594 return false; 3595 } 3596 3597 if (offscreen_size_ == size) 3598 return true; 3599 3600 offscreen_size_ = size; 3601 int w = offscreen_size_.width(); 3602 int h = offscreen_size_.height(); 3603 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { 3604 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3605 << "to allocate storage due to excessive dimensions."; 3606 return false; 3607 } 3608 3609 // Reallocate the offscreen target buffers. 3610 DCHECK(offscreen_target_color_format_); 3611 if (IsOffscreenBufferMultisampled()) { 3612 if (!offscreen_target_color_render_buffer_->AllocateStorage( 3613 feature_info_.get(), 3614 offscreen_size_, 3615 offscreen_target_color_format_, 3616 offscreen_target_samples_)) { 3617 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3618 << "to allocate storage for offscreen target color buffer."; 3619 return false; 3620 } 3621 } else { 3622 if (!offscreen_target_color_texture_->AllocateStorage( 3623 offscreen_size_, offscreen_target_color_format_, false)) { 3624 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3625 << "to allocate storage for offscreen target color texture."; 3626 return false; 3627 } 3628 } 3629 if (offscreen_target_depth_format_ && 3630 !offscreen_target_depth_render_buffer_->AllocateStorage( 3631 feature_info_.get(), 3632 offscreen_size_, 3633 offscreen_target_depth_format_, 3634 offscreen_target_samples_)) { 3635 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3636 << "to allocate storage for offscreen target depth buffer."; 3637 return false; 3638 } 3639 if (offscreen_target_stencil_format_ && 3640 !offscreen_target_stencil_render_buffer_->AllocateStorage( 3641 feature_info_.get(), 3642 offscreen_size_, 3643 offscreen_target_stencil_format_, 3644 offscreen_target_samples_)) { 3645 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3646 << "to allocate storage for offscreen target stencil buffer."; 3647 return false; 3648 } 3649 3650 // Attach the offscreen target buffers to the target frame buffer. 3651 if (IsOffscreenBufferMultisampled()) { 3652 offscreen_target_frame_buffer_->AttachRenderBuffer( 3653 GL_COLOR_ATTACHMENT0, 3654 offscreen_target_color_render_buffer_.get()); 3655 } else { 3656 offscreen_target_frame_buffer_->AttachRenderTexture( 3657 offscreen_target_color_texture_.get()); 3658 } 3659 if (offscreen_target_depth_format_) { 3660 offscreen_target_frame_buffer_->AttachRenderBuffer( 3661 GL_DEPTH_ATTACHMENT, 3662 offscreen_target_depth_render_buffer_.get()); 3663 } 3664 const bool packed_depth_stencil = 3665 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3666 if (packed_depth_stencil) { 3667 offscreen_target_frame_buffer_->AttachRenderBuffer( 3668 GL_STENCIL_ATTACHMENT, 3669 offscreen_target_depth_render_buffer_.get()); 3670 } else if (offscreen_target_stencil_format_) { 3671 offscreen_target_frame_buffer_->AttachRenderBuffer( 3672 GL_STENCIL_ATTACHMENT, 3673 offscreen_target_stencil_render_buffer_.get()); 3674 } 3675 3676 if (offscreen_target_frame_buffer_->CheckStatus() != 3677 GL_FRAMEBUFFER_COMPLETE) { 3678 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3679 << "because offscreen FBO was incomplete."; 3680 return false; 3681 } 3682 3683 // Clear the target frame buffer. 3684 { 3685 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); 3686 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3687 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3688 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3689 glClearStencil(0); 3690 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); 3691 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); 3692 glClearDepth(0); 3693 state_.SetDeviceDepthMask(GL_TRUE); 3694 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 3695 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 3696 RestoreClearState(); 3697 } 3698 3699 // Destroy the offscreen resolved framebuffers. 3700 if (offscreen_resolved_frame_buffer_.get()) 3701 offscreen_resolved_frame_buffer_->Destroy(); 3702 if (offscreen_resolved_color_texture_.get()) 3703 offscreen_resolved_color_texture_->Destroy(); 3704 offscreen_resolved_color_texture_.reset(); 3705 offscreen_resolved_frame_buffer_.reset(); 3706 3707 return true; 3708 } 3709 3710 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size, 3711 const void* cmd_data) { 3712 const gles2::cmds::ResizeCHROMIUM& c = 3713 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data); 3714 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws()) 3715 return error::kDeferCommandUntilLater; 3716 3717 GLuint width = static_cast<GLuint>(c.width); 3718 GLuint height = static_cast<GLuint>(c.height); 3719 GLfloat scale_factor = c.scale_factor; 3720 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); 3721 3722 width = std::max(1U, width); 3723 height = std::max(1U, height); 3724 3725 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \ 3726 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 3727 // Make sure that we are done drawing to the back buffer before resizing. 3728 glFinish(); 3729 #endif 3730 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3731 if (is_offscreen) { 3732 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) { 3733 LOG(ERROR) << "GLES2DecoderImpl: Context lost because " 3734 << "ResizeOffscreenFrameBuffer failed."; 3735 return error::kLostContext; 3736 } 3737 } 3738 3739 if (!resize_callback_.is_null()) { 3740 resize_callback_.Run(gfx::Size(width, height), scale_factor); 3741 DCHECK(context_->IsCurrent(surface_.get())); 3742 if (!context_->IsCurrent(surface_.get())) { 3743 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer " 3744 << "current after resize callback."; 3745 return error::kLostContext; 3746 } 3747 } 3748 3749 return error::kNoError; 3750 } 3751 3752 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { 3753 if (command_id > kStartPoint && command_id < kNumCommands) { 3754 return gles2::GetCommandName(static_cast<CommandId>(command_id)); 3755 } 3756 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 3757 } 3758 3759 // Decode a command, and call the corresponding GL functions. 3760 // NOTE: DoCommand() is slower than calling DoCommands() on larger batches 3761 // of commands at once, and is now only used for tests that need to track 3762 // individual commands. 3763 error::Error GLES2DecoderImpl::DoCommand(unsigned int command, 3764 unsigned int arg_count, 3765 const void* cmd_data) { 3766 return DoCommands(1, cmd_data, arg_count + 1, 0); 3767 } 3768 3769 // Decode multiple commands, and call the corresponding GL functions. 3770 // NOTE: 'buffer' is a pointer to the command buffer. As such, it could be 3771 // changed by a (malicious) client at any time, so if validation has to happen, 3772 // it should operate on a copy of them. 3773 // NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the 3774 // interest of performance in this critical execution loop. 3775 template <bool DebugImpl> 3776 error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, 3777 const void* buffer, 3778 int num_entries, 3779 int* entries_processed) { 3780 commands_to_process_ = num_commands; 3781 error::Error result = error::kNoError; 3782 const CommandBufferEntry* cmd_data = 3783 static_cast<const CommandBufferEntry*>(buffer); 3784 int process_pos = 0; 3785 unsigned int command = 0; 3786 3787 while (process_pos < num_entries && result == error::kNoError && 3788 commands_to_process_--) { 3789 const unsigned int size = cmd_data->value_header.size; 3790 command = cmd_data->value_header.command; 3791 3792 if (size == 0) { 3793 result = error::kInvalidSize; 3794 break; 3795 } 3796 3797 if (static_cast<int>(size) + process_pos > num_entries) { 3798 result = error::kOutOfBounds; 3799 break; 3800 } 3801 3802 if (DebugImpl) { 3803 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"), 3804 GetCommandName(command)); 3805 3806 if (log_commands()) { 3807 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" 3808 << "cmd: " << GetCommandName(command); 3809 } 3810 } 3811 3812 const unsigned int arg_count = size - 1; 3813 unsigned int command_index = command - kStartPoint - 1; 3814 if (command_index < arraysize(command_info)) { 3815 const CommandInfo& info = command_info[command_index]; 3816 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); 3817 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || 3818 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { 3819 bool doing_gpu_trace = false; 3820 if (DebugImpl && gpu_trace_commands_) { 3821 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) { 3822 doing_gpu_trace = true; 3823 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder); 3824 } 3825 } 3826 3827 uint32 immediate_data_size = (arg_count - info_arg_count) * 3828 sizeof(CommandBufferEntry); // NOLINT 3829 3830 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data); 3831 3832 if (DebugImpl && doing_gpu_trace) 3833 gpu_tracer_->End(kTraceDecoder); 3834 3835 if (DebugImpl && debug()) { 3836 GLenum error; 3837 while ((error = glGetError()) != GL_NO_ERROR) { 3838 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] " 3839 << "GL ERROR: " << GLES2Util::GetStringEnum(error) 3840 << " : " << GetCommandName(command); 3841 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver"); 3842 } 3843 } 3844 } else { 3845 result = error::kInvalidArguments; 3846 } 3847 } else { 3848 result = DoCommonCommand(command, arg_count, cmd_data); 3849 } 3850 3851 if (DebugImpl) { 3852 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"), 3853 GetCommandName(command)); 3854 } 3855 3856 if (result == error::kNoError && 3857 current_decoder_error_ != error::kNoError) { 3858 result = current_decoder_error_; 3859 current_decoder_error_ = error::kNoError; 3860 } 3861 3862 if (result != error::kDeferCommandUntilLater) { 3863 process_pos += size; 3864 cmd_data += size; 3865 } 3866 } 3867 3868 if (entries_processed) 3869 *entries_processed = process_pos; 3870 3871 if (error::IsError(result)) { 3872 LOG(ERROR) << "Error: " << result << " for Command " 3873 << GetCommandName(command); 3874 } 3875 3876 return result; 3877 } 3878 3879 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands, 3880 const void* buffer, 3881 int num_entries, 3882 int* entries_processed) { 3883 if (gpu_debug_commands_) { 3884 return DoCommandsImpl<true>( 3885 num_commands, buffer, num_entries, entries_processed); 3886 } else { 3887 return DoCommandsImpl<false>( 3888 num_commands, buffer, num_entries, entries_processed); 3889 } 3890 } 3891 3892 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { 3893 buffer_manager()->RemoveBuffer(client_id); 3894 } 3895 3896 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { 3897 if (GetProgram(client_id)) { 3898 return false; 3899 } 3900 GLuint service_id = glCreateProgram(); 3901 if (service_id != 0) { 3902 CreateProgram(client_id, service_id); 3903 } 3904 return true; 3905 } 3906 3907 bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { 3908 if (GetShader(client_id)) { 3909 return false; 3910 } 3911 GLuint service_id = glCreateShader(type); 3912 if (service_id != 0) { 3913 CreateShader(client_id, service_id, type); 3914 } 3915 return true; 3916 } 3917 3918 void GLES2DecoderImpl::DoFinish() { 3919 glFinish(); 3920 ProcessPendingReadPixels(); 3921 ProcessPendingQueries(); 3922 } 3923 3924 void GLES2DecoderImpl::DoFlush() { 3925 glFlush(); 3926 ProcessPendingQueries(); 3927 } 3928 3929 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { 3930 GLuint texture_index = texture_unit - GL_TEXTURE0; 3931 if (texture_index >= state_.texture_units.size()) { 3932 LOCAL_SET_GL_ERROR_INVALID_ENUM( 3933 "glActiveTexture", texture_unit, "texture_unit"); 3934 return; 3935 } 3936 state_.active_texture_unit = texture_index; 3937 glActiveTexture(texture_unit); 3938 } 3939 3940 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { 3941 Buffer* buffer = NULL; 3942 GLuint service_id = 0; 3943 if (client_id != 0) { 3944 buffer = GetBuffer(client_id); 3945 if (!buffer) { 3946 if (!group_->bind_generates_resource()) { 3947 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 3948 "glBindBuffer", 3949 "id not generated by glGenBuffers"); 3950 return; 3951 } 3952 3953 // It's a new id so make a buffer buffer for it. 3954 glGenBuffersARB(1, &service_id); 3955 CreateBuffer(client_id, service_id); 3956 buffer = GetBuffer(client_id); 3957 IdAllocatorInterface* id_allocator = 3958 group_->GetIdAllocator(id_namespaces::kBuffers); 3959 id_allocator->MarkAsUsed(client_id); 3960 } 3961 } 3962 LogClientServiceForInfo(buffer, client_id, "glBindBuffer"); 3963 if (buffer) { 3964 if (!buffer_manager()->SetTarget(buffer, target)) { 3965 LOCAL_SET_GL_ERROR( 3966 GL_INVALID_OPERATION, 3967 "glBindBuffer", "buffer bound to more than 1 target"); 3968 return; 3969 } 3970 service_id = buffer->service_id(); 3971 } 3972 switch (target) { 3973 case GL_ARRAY_BUFFER: 3974 state_.bound_array_buffer = buffer; 3975 break; 3976 case GL_ELEMENT_ARRAY_BUFFER: 3977 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer); 3978 break; 3979 default: 3980 NOTREACHED(); // Validation should prevent us getting here. 3981 break; 3982 } 3983 glBindBuffer(target, service_id); 3984 } 3985 3986 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha( 3987 bool all_draw_buffers) { 3988 Framebuffer* framebuffer = 3989 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3990 if (!all_draw_buffers || !framebuffer) { 3991 return (GLES2Util::GetChannelsForFormat( 3992 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0; 3993 } 3994 return framebuffer->HasAlphaMRT(); 3995 } 3996 3997 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() { 3998 Framebuffer* framebuffer = 3999 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 4000 if (framebuffer) { 4001 return framebuffer->HasDepthAttachment(); 4002 } 4003 if (offscreen_target_frame_buffer_.get()) { 4004 return offscreen_target_depth_format_ != 0; 4005 } 4006 return back_buffer_has_depth_; 4007 } 4008 4009 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { 4010 Framebuffer* framebuffer = 4011 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 4012 if (framebuffer) { 4013 return framebuffer->HasStencilAttachment(); 4014 } 4015 if (offscreen_target_frame_buffer_.get()) { 4016 return offscreen_target_stencil_format_ != 0 || 4017 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 4018 } 4019 return back_buffer_has_stencil_; 4020 } 4021 4022 void GLES2DecoderImpl::ApplyDirtyState() { 4023 if (framebuffer_state_.clear_state_dirty) { 4024 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true); 4025 state_.SetDeviceColorMask(state_.color_mask_red, 4026 state_.color_mask_green, 4027 state_.color_mask_blue, 4028 state_.color_mask_alpha && have_alpha); 4029 4030 bool have_depth = BoundFramebufferHasDepthAttachment(); 4031 state_.SetDeviceDepthMask(state_.depth_mask && have_depth); 4032 4033 bool have_stencil = BoundFramebufferHasStencilAttachment(); 4034 state_.SetDeviceStencilMaskSeparate( 4035 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0); 4036 state_.SetDeviceStencilMaskSeparate( 4037 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0); 4038 4039 state_.SetDeviceCapabilityState( 4040 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth); 4041 state_.SetDeviceCapabilityState( 4042 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil); 4043 framebuffer_state_.clear_state_dirty = false; 4044 } 4045 } 4046 4047 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const { 4048 return (offscreen_target_frame_buffer_.get()) 4049 ? offscreen_target_frame_buffer_->id() 4050 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0); 4051 } 4052 4053 void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) { 4054 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState", 4055 "context", logger_.GetLogPrefix()); 4056 // Restore the Framebuffer first because of bugs in Intel drivers. 4057 // Intel drivers incorrectly clip the viewport settings to 4058 // the size of the current framebuffer object. 4059 RestoreFramebufferBindings(); 4060 state_.RestoreState(prev_state); 4061 } 4062 4063 void GLES2DecoderImpl::RestoreFramebufferBindings() const { 4064 GLuint service_id = 4065 framebuffer_state_.bound_draw_framebuffer.get() 4066 ? framebuffer_state_.bound_draw_framebuffer->service_id() 4067 : GetBackbufferServiceId(); 4068 if (!features().chromium_framebuffer_multisample) { 4069 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); 4070 } else { 4071 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); 4072 service_id = framebuffer_state_.bound_read_framebuffer.get() 4073 ? framebuffer_state_.bound_read_framebuffer->service_id() 4074 : GetBackbufferServiceId(); 4075 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id); 4076 } 4077 OnFboChanged(); 4078 } 4079 4080 void GLES2DecoderImpl::RestoreRenderbufferBindings() { 4081 state_.RestoreRenderbufferBindings(); 4082 } 4083 4084 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const { 4085 Texture* texture = texture_manager()->GetTextureForServiceId(service_id); 4086 if (texture) { 4087 GLenum target = texture->target(); 4088 glBindTexture(target, service_id); 4089 glTexParameteri( 4090 target, GL_TEXTURE_WRAP_S, texture->wrap_s()); 4091 glTexParameteri( 4092 target, GL_TEXTURE_WRAP_T, texture->wrap_t()); 4093 glTexParameteri( 4094 target, GL_TEXTURE_MIN_FILTER, texture->min_filter()); 4095 glTexParameteri( 4096 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter()); 4097 RestoreTextureUnitBindings(state_.active_texture_unit); 4098 } 4099 } 4100 4101 void GLES2DecoderImpl::ClearAllAttributes() const { 4102 // Must use native VAO 0, as RestoreAllAttributes can't fully restore 4103 // other VAOs. 4104 if (feature_info_->feature_flags().native_vertex_array_object) 4105 glBindVertexArrayOES(0); 4106 4107 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) { 4108 if (i != 0) // Never disable attribute 0 4109 glDisableVertexAttribArray(i); 4110 if(features().angle_instanced_arrays) 4111 glVertexAttribDivisorANGLE(i, 0); 4112 } 4113 } 4114 4115 void GLES2DecoderImpl::RestoreAllAttributes() const { 4116 state_.RestoreVertexAttribs(); 4117 } 4118 4119 void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) { 4120 state_.SetIgnoreCachedStateForTest(ignore); 4121 } 4122 4123 void GLES2DecoderImpl::OnFboChanged() const { 4124 if (workarounds().restore_scissor_on_fbo_change) 4125 state_.fbo_binding_for_scissor_workaround_dirty_ = true; 4126 } 4127 4128 // Called after the FBO is checked for completeness. 4129 void GLES2DecoderImpl::OnUseFramebuffer() const { 4130 if (state_.fbo_binding_for_scissor_workaround_dirty_) { 4131 state_.fbo_binding_for_scissor_workaround_dirty_ = false; 4132 // The driver forgets the correct scissor when modifying the FBO binding. 4133 glScissor(state_.scissor_x, 4134 state_.scissor_y, 4135 state_.scissor_width, 4136 state_.scissor_height); 4137 4138 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker, 4139 // it's unclear how this bug works. 4140 glFlush(); 4141 } 4142 } 4143 4144 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { 4145 Framebuffer* framebuffer = NULL; 4146 GLuint service_id = 0; 4147 if (client_id != 0) { 4148 framebuffer = GetFramebuffer(client_id); 4149 if (!framebuffer) { 4150 if (!group_->bind_generates_resource()) { 4151 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4152 "glBindFramebuffer", 4153 "id not generated by glGenFramebuffers"); 4154 return; 4155 } 4156 4157 // It's a new id so make a framebuffer framebuffer for it. 4158 glGenFramebuffersEXT(1, &service_id); 4159 CreateFramebuffer(client_id, service_id); 4160 framebuffer = GetFramebuffer(client_id); 4161 IdAllocatorInterface* id_allocator = 4162 group_->GetIdAllocator(id_namespaces::kFramebuffers); 4163 id_allocator->MarkAsUsed(client_id); 4164 } else { 4165 service_id = framebuffer->service_id(); 4166 } 4167 framebuffer->MarkAsValid(); 4168 } 4169 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer"); 4170 4171 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { 4172 framebuffer_state_.bound_draw_framebuffer = framebuffer; 4173 } 4174 4175 // vmiura: This looks like dup code 4176 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { 4177 framebuffer_state_.bound_read_framebuffer = framebuffer; 4178 } 4179 4180 framebuffer_state_.clear_state_dirty = true; 4181 4182 // If we are rendering to the backbuffer get the FBO id for any simulated 4183 // backbuffer. 4184 if (framebuffer == NULL) { 4185 service_id = GetBackbufferServiceId(); 4186 } 4187 4188 glBindFramebufferEXT(target, service_id); 4189 OnFboChanged(); 4190 } 4191 4192 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { 4193 Renderbuffer* renderbuffer = NULL; 4194 GLuint service_id = 0; 4195 if (client_id != 0) { 4196 renderbuffer = GetRenderbuffer(client_id); 4197 if (!renderbuffer) { 4198 if (!group_->bind_generates_resource()) { 4199 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4200 "glBindRenderbuffer", 4201 "id not generated by glGenRenderbuffers"); 4202 return; 4203 } 4204 4205 // It's a new id so make a renderbuffer for it. 4206 glGenRenderbuffersEXT(1, &service_id); 4207 CreateRenderbuffer(client_id, service_id); 4208 renderbuffer = GetRenderbuffer(client_id); 4209 IdAllocatorInterface* id_allocator = 4210 group_->GetIdAllocator(id_namespaces::kRenderbuffers); 4211 id_allocator->MarkAsUsed(client_id); 4212 } else { 4213 service_id = renderbuffer->service_id(); 4214 } 4215 renderbuffer->MarkAsValid(); 4216 } 4217 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer"); 4218 state_.bound_renderbuffer = renderbuffer; 4219 state_.bound_renderbuffer_valid = true; 4220 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id); 4221 } 4222 4223 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { 4224 TextureRef* texture_ref = NULL; 4225 GLuint service_id = 0; 4226 if (client_id != 0) { 4227 texture_ref = GetTexture(client_id); 4228 if (!texture_ref) { 4229 if (!group_->bind_generates_resource()) { 4230 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4231 "glBindTexture", 4232 "id not generated by glGenTextures"); 4233 return; 4234 } 4235 4236 // It's a new id so make a texture texture for it. 4237 glGenTextures(1, &service_id); 4238 DCHECK_NE(0u, service_id); 4239 CreateTexture(client_id, service_id); 4240 texture_ref = GetTexture(client_id); 4241 IdAllocatorInterface* id_allocator = 4242 group_->GetIdAllocator(id_namespaces::kTextures); 4243 id_allocator->MarkAsUsed(client_id); 4244 } 4245 } else { 4246 texture_ref = texture_manager()->GetDefaultTextureInfo(target); 4247 } 4248 4249 // Check the texture exists 4250 if (texture_ref) { 4251 Texture* texture = texture_ref->texture(); 4252 // Check that we are not trying to bind it to a different target. 4253 if (texture->target() != 0 && texture->target() != target) { 4254 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4255 "glBindTexture", 4256 "texture bound to more than 1 target."); 4257 return; 4258 } 4259 LogClientServiceForInfo(texture, client_id, "glBindTexture"); 4260 if (texture->target() == 0) { 4261 texture_manager()->SetTarget(texture_ref, target); 4262 } 4263 glBindTexture(target, texture->service_id()); 4264 } else { 4265 glBindTexture(target, 0); 4266 } 4267 4268 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4269 unit.bind_target = target; 4270 switch (target) { 4271 case GL_TEXTURE_2D: 4272 unit.bound_texture_2d = texture_ref; 4273 break; 4274 case GL_TEXTURE_CUBE_MAP: 4275 unit.bound_texture_cube_map = texture_ref; 4276 break; 4277 case GL_TEXTURE_EXTERNAL_OES: 4278 unit.bound_texture_external_oes = texture_ref; 4279 break; 4280 case GL_TEXTURE_RECTANGLE_ARB: 4281 unit.bound_texture_rectangle_arb = texture_ref; 4282 break; 4283 default: 4284 NOTREACHED(); // Validation should prevent us getting here. 4285 break; 4286 } 4287 } 4288 4289 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { 4290 if (state_.vertex_attrib_manager->Enable(index, false)) { 4291 if (index != 0 || 4292 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 4293 glDisableVertexAttribArray(index); 4294 } 4295 } else { 4296 LOCAL_SET_GL_ERROR( 4297 GL_INVALID_VALUE, 4298 "glDisableVertexAttribArray", "index out of range"); 4299 } 4300 } 4301 4302 void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, 4303 GLsizei numAttachments, 4304 const GLenum* attachments) { 4305 Framebuffer* framebuffer = 4306 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4307 4308 // Validates the attachments. If one of them fails 4309 // the whole command fails. 4310 for (GLsizei i = 0; i < numAttachments; ++i) { 4311 if ((framebuffer && 4312 !validators_->attachment.IsValid(attachments[i])) || 4313 (!framebuffer && 4314 !validators_->backbuffer_attachment.IsValid(attachments[i]))) { 4315 LOCAL_SET_GL_ERROR_INVALID_ENUM( 4316 "glDiscardFramebufferEXT", attachments[i], "attachments"); 4317 return; 4318 } 4319 } 4320 4321 // Marks each one of them as not cleared 4322 for (GLsizei i = 0; i < numAttachments; ++i) { 4323 if (framebuffer) { 4324 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(), 4325 texture_manager(), 4326 attachments[i], 4327 false); 4328 } else { 4329 switch (attachments[i]) { 4330 case GL_COLOR_EXT: 4331 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT; 4332 break; 4333 case GL_DEPTH_EXT: 4334 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT; 4335 case GL_STENCIL_EXT: 4336 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT; 4337 break; 4338 default: 4339 NOTREACHED(); 4340 break; 4341 } 4342 } 4343 } 4344 4345 // If the default framebuffer is bound but we are still rendering to an 4346 // FBO, translate attachment names that refer to default framebuffer 4347 // channels to corresponding framebuffer attachments. 4348 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]); 4349 for (GLsizei i = 0; i < numAttachments; ++i) { 4350 GLenum attachment = attachments[i]; 4351 if (!framebuffer && GetBackbufferServiceId()) { 4352 switch (attachment) { 4353 case GL_COLOR_EXT: 4354 attachment = GL_COLOR_ATTACHMENT0; 4355 break; 4356 case GL_DEPTH_EXT: 4357 attachment = GL_DEPTH_ATTACHMENT; 4358 break; 4359 case GL_STENCIL_EXT: 4360 attachment = GL_STENCIL_ATTACHMENT; 4361 break; 4362 default: 4363 NOTREACHED(); 4364 return; 4365 } 4366 } 4367 translated_attachments[i] = attachment; 4368 } 4369 4370 ScopedRenderTo do_render(framebuffer); 4371 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get()); 4372 } 4373 4374 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { 4375 if (state_.vertex_attrib_manager->Enable(index, true)) { 4376 glEnableVertexAttribArray(index); 4377 } else { 4378 LOCAL_SET_GL_ERROR( 4379 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range"); 4380 } 4381 } 4382 4383 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { 4384 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 4385 &state_, target); 4386 if (!texture_ref || 4387 !texture_manager()->CanGenerateMipmaps(texture_ref)) { 4388 LOCAL_SET_GL_ERROR( 4389 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips"); 4390 return; 4391 } 4392 4393 if (target == GL_TEXTURE_CUBE_MAP) { 4394 for (int i = 0; i < 6; ++i) { 4395 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; 4396 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) { 4397 LOCAL_SET_GL_ERROR( 4398 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4399 return; 4400 } 4401 } 4402 } else { 4403 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) { 4404 LOCAL_SET_GL_ERROR( 4405 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4406 return; 4407 } 4408 } 4409 4410 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap"); 4411 // Workaround for Mac driver bug. In the large scheme of things setting 4412 // glTexParamter twice for glGenerateMipmap is probably not a lage performance 4413 // hit so there's probably no need to make this conditional. The bug appears 4414 // to be that if the filtering mode is set to something that doesn't require 4415 // mipmaps for rendering, or is never set to something other than the default, 4416 // then glGenerateMipmap misbehaves. 4417 if (workarounds().set_texture_filter_before_generating_mipmap) { 4418 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 4419 } 4420 glGenerateMipmapEXT(target); 4421 if (workarounds().set_texture_filter_before_generating_mipmap) { 4422 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 4423 texture_ref->texture()->min_filter()); 4424 } 4425 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap"); 4426 if (error == GL_NO_ERROR) { 4427 texture_manager()->MarkMipmapsGenerated(texture_ref); 4428 } 4429 } 4430 4431 bool GLES2DecoderImpl::GetHelper( 4432 GLenum pname, GLint* params, GLsizei* num_written) { 4433 DCHECK(num_written); 4434 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 4435 switch (pname) { 4436 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 4437 *num_written = 1; 4438 // Return the GL implementation's preferred format and (see below type) 4439 // if we have the GL extension that exposes this. This allows the GPU 4440 // client to use the implementation's preferred format for glReadPixels 4441 // for optimisation. 4442 // 4443 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error 4444 // case when requested on integer/floating point buffers but which is 4445 // acceptable on GLES2 and with the GL_OES_read_format extension. 4446 // 4447 // Therefore if an error occurs we swallow the error and use the 4448 // internal implementation. 4449 if (params) { 4450 if (context_->HasExtension("GL_OES_read_format")) { 4451 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper", 4452 GetErrorState()); 4453 glGetIntegerv(pname, params); 4454 if (glGetError() == GL_NO_ERROR) 4455 return true; 4456 } 4457 *params = GLES2Util::GetPreferredGLReadPixelsFormat( 4458 GetBoundReadFrameBufferInternalFormat()); 4459 } 4460 return true; 4461 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 4462 *num_written = 1; 4463 if (params) { 4464 if (context_->HasExtension("GL_OES_read_format")) { 4465 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper", 4466 GetErrorState()); 4467 glGetIntegerv(pname, params); 4468 if (glGetError() == GL_NO_ERROR) 4469 return true; 4470 } 4471 *params = GLES2Util::GetPreferredGLReadPixelsType( 4472 GetBoundReadFrameBufferInternalFormat(), 4473 GetBoundReadFrameBufferTextureType()); 4474 } 4475 return true; 4476 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 4477 *num_written = 1; 4478 if (params) { 4479 *params = group_->max_fragment_uniform_vectors(); 4480 } 4481 return true; 4482 case GL_MAX_VARYING_VECTORS: 4483 *num_written = 1; 4484 if (params) { 4485 *params = group_->max_varying_vectors(); 4486 } 4487 return true; 4488 case GL_MAX_VERTEX_UNIFORM_VECTORS: 4489 *num_written = 1; 4490 if (params) { 4491 *params = group_->max_vertex_uniform_vectors(); 4492 } 4493 return true; 4494 } 4495 } 4496 switch (pname) { 4497 case GL_MAX_VIEWPORT_DIMS: 4498 if (offscreen_target_frame_buffer_.get()) { 4499 *num_written = 2; 4500 if (params) { 4501 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4502 params[1] = renderbuffer_manager()->max_renderbuffer_size(); 4503 } 4504 return true; 4505 } 4506 return false; 4507 case GL_MAX_SAMPLES: 4508 *num_written = 1; 4509 if (params) { 4510 params[0] = renderbuffer_manager()->max_samples(); 4511 } 4512 return true; 4513 case GL_MAX_RENDERBUFFER_SIZE: 4514 *num_written = 1; 4515 if (params) { 4516 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4517 } 4518 return true; 4519 case GL_MAX_TEXTURE_SIZE: 4520 *num_written = 1; 4521 if (params) { 4522 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D); 4523 } 4524 return true; 4525 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 4526 *num_written = 1; 4527 if (params) { 4528 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP); 4529 } 4530 return true; 4531 case GL_MAX_COLOR_ATTACHMENTS_EXT: 4532 *num_written = 1; 4533 if (params) { 4534 params[0] = group_->max_color_attachments(); 4535 } 4536 return true; 4537 case GL_MAX_DRAW_BUFFERS_ARB: 4538 *num_written = 1; 4539 if (params) { 4540 params[0] = group_->max_draw_buffers(); 4541 } 4542 return true; 4543 case GL_ALPHA_BITS: 4544 *num_written = 1; 4545 if (params) { 4546 GLint v = 0; 4547 glGetIntegerv(GL_ALPHA_BITS, &v); 4548 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; 4549 } 4550 return true; 4551 case GL_DEPTH_BITS: 4552 *num_written = 1; 4553 if (params) { 4554 GLint v = 0; 4555 glGetIntegerv(GL_DEPTH_BITS, &v); 4556 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; 4557 } 4558 return true; 4559 case GL_STENCIL_BITS: 4560 *num_written = 1; 4561 if (params) { 4562 GLint v = 0; 4563 glGetIntegerv(GL_STENCIL_BITS, &v); 4564 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; 4565 } 4566 return true; 4567 case GL_COMPRESSED_TEXTURE_FORMATS: 4568 *num_written = validators_->compressed_texture_format.GetValues().size(); 4569 if (params) { 4570 for (GLint ii = 0; ii < *num_written; ++ii) { 4571 params[ii] = validators_->compressed_texture_format.GetValues()[ii]; 4572 } 4573 } 4574 return true; 4575 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 4576 *num_written = 1; 4577 if (params) { 4578 *params = validators_->compressed_texture_format.GetValues().size(); 4579 } 4580 return true; 4581 case GL_NUM_SHADER_BINARY_FORMATS: 4582 *num_written = 1; 4583 if (params) { 4584 *params = validators_->shader_binary_format.GetValues().size(); 4585 } 4586 return true; 4587 case GL_SHADER_BINARY_FORMATS: 4588 *num_written = validators_->shader_binary_format.GetValues().size(); 4589 if (params) { 4590 for (GLint ii = 0; ii < *num_written; ++ii) { 4591 params[ii] = validators_->shader_binary_format.GetValues()[ii]; 4592 } 4593 } 4594 return true; 4595 case GL_SHADER_COMPILER: 4596 *num_written = 1; 4597 if (params) { 4598 *params = GL_TRUE; 4599 } 4600 return true; 4601 case GL_ARRAY_BUFFER_BINDING: 4602 *num_written = 1; 4603 if (params) { 4604 if (state_.bound_array_buffer.get()) { 4605 GLuint client_id = 0; 4606 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(), 4607 &client_id); 4608 *params = client_id; 4609 } else { 4610 *params = 0; 4611 } 4612 } 4613 return true; 4614 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 4615 *num_written = 1; 4616 if (params) { 4617 if (state_.vertex_attrib_manager->element_array_buffer()) { 4618 GLuint client_id = 0; 4619 buffer_manager()->GetClientId( 4620 state_.vertex_attrib_manager->element_array_buffer()-> 4621 service_id(), &client_id); 4622 *params = client_id; 4623 } else { 4624 *params = 0; 4625 } 4626 } 4627 return true; 4628 case GL_FRAMEBUFFER_BINDING: 4629 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) 4630 *num_written = 1; 4631 if (params) { 4632 Framebuffer* framebuffer = 4633 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4634 if (framebuffer) { 4635 GLuint client_id = 0; 4636 framebuffer_manager()->GetClientId( 4637 framebuffer->service_id(), &client_id); 4638 *params = client_id; 4639 } else { 4640 *params = 0; 4641 } 4642 } 4643 return true; 4644 case GL_READ_FRAMEBUFFER_BINDING_EXT: 4645 *num_written = 1; 4646 if (params) { 4647 Framebuffer* framebuffer = 4648 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 4649 if (framebuffer) { 4650 GLuint client_id = 0; 4651 framebuffer_manager()->GetClientId( 4652 framebuffer->service_id(), &client_id); 4653 *params = client_id; 4654 } else { 4655 *params = 0; 4656 } 4657 } 4658 return true; 4659 case GL_RENDERBUFFER_BINDING: 4660 *num_written = 1; 4661 if (params) { 4662 Renderbuffer* renderbuffer = 4663 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4664 if (renderbuffer) { 4665 *params = renderbuffer->client_id(); 4666 } else { 4667 *params = 0; 4668 } 4669 } 4670 return true; 4671 case GL_CURRENT_PROGRAM: 4672 *num_written = 1; 4673 if (params) { 4674 if (state_.current_program.get()) { 4675 GLuint client_id = 0; 4676 program_manager()->GetClientId( 4677 state_.current_program->service_id(), &client_id); 4678 *params = client_id; 4679 } else { 4680 *params = 0; 4681 } 4682 } 4683 return true; 4684 case GL_VERTEX_ARRAY_BINDING_OES: 4685 *num_written = 1; 4686 if (params) { 4687 if (state_.vertex_attrib_manager.get() != 4688 state_.default_vertex_attrib_manager.get()) { 4689 GLuint client_id = 0; 4690 vertex_array_manager_->GetClientId( 4691 state_.vertex_attrib_manager->service_id(), &client_id); 4692 *params = client_id; 4693 } else { 4694 *params = 0; 4695 } 4696 } 4697 return true; 4698 case GL_TEXTURE_BINDING_2D: 4699 *num_written = 1; 4700 if (params) { 4701 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4702 if (unit.bound_texture_2d.get()) { 4703 *params = unit.bound_texture_2d->client_id(); 4704 } else { 4705 *params = 0; 4706 } 4707 } 4708 return true; 4709 case GL_TEXTURE_BINDING_CUBE_MAP: 4710 *num_written = 1; 4711 if (params) { 4712 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4713 if (unit.bound_texture_cube_map.get()) { 4714 *params = unit.bound_texture_cube_map->client_id(); 4715 } else { 4716 *params = 0; 4717 } 4718 } 4719 return true; 4720 case GL_TEXTURE_BINDING_EXTERNAL_OES: 4721 *num_written = 1; 4722 if (params) { 4723 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4724 if (unit.bound_texture_external_oes.get()) { 4725 *params = unit.bound_texture_external_oes->client_id(); 4726 } else { 4727 *params = 0; 4728 } 4729 } 4730 return true; 4731 case GL_TEXTURE_BINDING_RECTANGLE_ARB: 4732 *num_written = 1; 4733 if (params) { 4734 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4735 if (unit.bound_texture_rectangle_arb.get()) { 4736 *params = unit.bound_texture_rectangle_arb->client_id(); 4737 } else { 4738 *params = 0; 4739 } 4740 } 4741 return true; 4742 case GL_UNPACK_FLIP_Y_CHROMIUM: 4743 *num_written = 1; 4744 if (params) { 4745 params[0] = unpack_flip_y_; 4746 } 4747 return true; 4748 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 4749 *num_written = 1; 4750 if (params) { 4751 params[0] = unpack_premultiply_alpha_; 4752 } 4753 return true; 4754 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 4755 *num_written = 1; 4756 if (params) { 4757 params[0] = unpack_unpremultiply_alpha_; 4758 } 4759 return true; 4760 case GL_BIND_GENERATES_RESOURCE_CHROMIUM: 4761 *num_written = 1; 4762 if (params) { 4763 params[0] = group_->bind_generates_resource() ? 1 : 0; 4764 } 4765 return true; 4766 default: 4767 if (pname >= GL_DRAW_BUFFER0_ARB && 4768 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { 4769 *num_written = 1; 4770 if (params) { 4771 Framebuffer* framebuffer = 4772 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4773 if (framebuffer) { 4774 params[0] = framebuffer->GetDrawBuffer(pname); 4775 } else { // backbuffer 4776 if (pname == GL_DRAW_BUFFER0_ARB) 4777 params[0] = group_->draw_buffer(); 4778 else 4779 params[0] = GL_NONE; 4780 } 4781 } 4782 return true; 4783 } 4784 *num_written = util_.GLGetNumValuesReturned(pname); 4785 return false; 4786 } 4787 } 4788 4789 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( 4790 GLenum pname, GLsizei* num_values) { 4791 if (state_.GetStateAsGLint(pname, NULL, num_values)) { 4792 return true; 4793 } 4794 return GetHelper(pname, NULL, num_values); 4795 } 4796 4797 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) { 4798 if (GL_MAX_SAMPLES == pname && 4799 features().use_img_for_multisampled_render_to_texture) { 4800 return GL_MAX_SAMPLES_IMG; 4801 } 4802 return pname; 4803 } 4804 4805 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { 4806 DCHECK(params); 4807 GLsizei num_written = 0; 4808 if (GetNumValuesReturnedForGLGet(pname, &num_written)) { 4809 scoped_ptr<GLint[]> values(new GLint[num_written]); 4810 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) { 4811 GetHelper(pname, values.get(), &num_written); 4812 } 4813 for (GLsizei ii = 0; ii < num_written; ++ii) { 4814 params[ii] = static_cast<GLboolean>(values[ii]); 4815 } 4816 } else { 4817 pname = AdjustGetPname(pname); 4818 glGetBooleanv(pname, params); 4819 } 4820 } 4821 4822 void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { 4823 DCHECK(params); 4824 GLsizei num_written = 0; 4825 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) { 4826 if (GetHelper(pname, NULL, &num_written)) { 4827 scoped_ptr<GLint[]> values(new GLint[num_written]); 4828 GetHelper(pname, values.get(), &num_written); 4829 for (GLsizei ii = 0; ii < num_written; ++ii) { 4830 params[ii] = static_cast<GLfloat>(values[ii]); 4831 } 4832 } else { 4833 pname = AdjustGetPname(pname); 4834 glGetFloatv(pname, params); 4835 } 4836 } 4837 } 4838 4839 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { 4840 DCHECK(params); 4841 GLsizei num_written; 4842 if (!state_.GetStateAsGLint(pname, params, &num_written) && 4843 !GetHelper(pname, params, &num_written)) { 4844 pname = AdjustGetPname(pname); 4845 glGetIntegerv(pname, params); 4846 } 4847 } 4848 4849 void GLES2DecoderImpl::DoGetProgramiv( 4850 GLuint program_id, GLenum pname, GLint* params) { 4851 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv"); 4852 if (!program) { 4853 return; 4854 } 4855 program->GetProgramiv(pname, params); 4856 } 4857 4858 void GLES2DecoderImpl::DoGetBufferParameteriv( 4859 GLenum target, GLenum pname, GLint* params) { 4860 // Just delegate it. Some validation is actually done before this. 4861 buffer_manager()->ValidateAndDoGetBufferParameteriv( 4862 &state_, target, pname, params); 4863 } 4864 4865 void GLES2DecoderImpl::DoBindAttribLocation( 4866 GLuint program_id, GLuint index, const char* name) { 4867 if (!StringIsValidForGLES(name)) { 4868 LOCAL_SET_GL_ERROR( 4869 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); 4870 return; 4871 } 4872 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4873 LOCAL_SET_GL_ERROR( 4874 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); 4875 return; 4876 } 4877 if (index >= group_->max_vertex_attribs()) { 4878 LOCAL_SET_GL_ERROR( 4879 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); 4880 return; 4881 } 4882 Program* program = GetProgramInfoNotShader( 4883 program_id, "glBindAttribLocation"); 4884 if (!program) { 4885 return; 4886 } 4887 program->SetAttribLocationBinding(name, static_cast<GLint>(index)); 4888 glBindAttribLocation(program->service_id(), index, name); 4889 } 4890 4891 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( 4892 uint32 immediate_data_size, 4893 const void* cmd_data) { 4894 const gles2::cmds::BindAttribLocationBucket& c = 4895 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data); 4896 GLuint program = static_cast<GLuint>(c.program); 4897 GLuint index = static_cast<GLuint>(c.index); 4898 Bucket* bucket = GetBucket(c.name_bucket_id); 4899 if (!bucket || bucket->size() == 0) { 4900 return error::kInvalidArguments; 4901 } 4902 std::string name_str; 4903 if (!bucket->GetAsString(&name_str)) { 4904 return error::kInvalidArguments; 4905 } 4906 DoBindAttribLocation(program, index, name_str.c_str()); 4907 return error::kNoError; 4908 } 4909 4910 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( 4911 GLuint program_id, GLint location, const char* name) { 4912 if (!StringIsValidForGLES(name)) { 4913 LOCAL_SET_GL_ERROR( 4914 GL_INVALID_VALUE, 4915 "glBindUniformLocationCHROMIUM", "Invalid character"); 4916 return; 4917 } 4918 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4919 LOCAL_SET_GL_ERROR( 4920 GL_INVALID_OPERATION, 4921 "glBindUniformLocationCHROMIUM", "reserved prefix"); 4922 return; 4923 } 4924 if (location < 0 || static_cast<uint32>(location) >= 4925 (group_->max_fragment_uniform_vectors() + 4926 group_->max_vertex_uniform_vectors()) * 4) { 4927 LOCAL_SET_GL_ERROR( 4928 GL_INVALID_VALUE, 4929 "glBindUniformLocationCHROMIUM", "location out of range"); 4930 return; 4931 } 4932 Program* program = GetProgramInfoNotShader( 4933 program_id, "glBindUniformLocationCHROMIUM"); 4934 if (!program) { 4935 return; 4936 } 4937 if (!program->SetUniformLocationBinding(name, location)) { 4938 LOCAL_SET_GL_ERROR( 4939 GL_INVALID_VALUE, 4940 "glBindUniformLocationCHROMIUM", "location out of range"); 4941 } 4942 } 4943 4944 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket( 4945 uint32 immediate_data_size, 4946 const void* cmd_data) { 4947 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c = 4948 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>( 4949 cmd_data); 4950 GLuint program = static_cast<GLuint>(c.program); 4951 GLint location = static_cast<GLint>(c.location); 4952 Bucket* bucket = GetBucket(c.name_bucket_id); 4953 if (!bucket || bucket->size() == 0) { 4954 return error::kInvalidArguments; 4955 } 4956 std::string name_str; 4957 if (!bucket->GetAsString(&name_str)) { 4958 return error::kInvalidArguments; 4959 } 4960 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4961 return error::kNoError; 4962 } 4963 4964 error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size, 4965 const void* cmd_data) { 4966 const gles2::cmds::DeleteShader& c = 4967 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data); 4968 GLuint client_id = c.shader; 4969 if (client_id) { 4970 Shader* shader = GetShader(client_id); 4971 if (shader) { 4972 if (!shader->IsDeleted()) { 4973 glDeleteShader(shader->service_id()); 4974 shader_manager()->MarkAsDeleted(shader); 4975 } 4976 } else { 4977 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); 4978 } 4979 } 4980 return error::kNoError; 4981 } 4982 4983 error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size, 4984 const void* cmd_data) { 4985 const gles2::cmds::DeleteProgram& c = 4986 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data); 4987 GLuint client_id = c.program; 4988 if (client_id) { 4989 Program* program = GetProgram(client_id); 4990 if (program) { 4991 if (!program->IsDeleted()) { 4992 program_manager()->MarkAsDeleted(shader_manager(), program); 4993 } 4994 } else { 4995 LOCAL_SET_GL_ERROR( 4996 GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); 4997 } 4998 } 4999 return error::kNoError; 5000 } 5001 5002 void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM( 5003 GLuint namespace_id, GLsizei n, const GLuint* ids) { 5004 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 5005 for (GLsizei ii = 0; ii < n; ++ii) { 5006 id_allocator->FreeID(ids[ii]); 5007 } 5008 } 5009 5010 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM( 5011 uint32 immediate_data_size, 5012 const void* cmd_data) { 5013 const gles2::cmds::DeleteSharedIdsCHROMIUM& c = 5014 *static_cast<const gles2::cmds::DeleteSharedIdsCHROMIUM*>(cmd_data); 5015 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 5016 GLsizei n = static_cast<GLsizei>(c.n); 5017 uint32 data_size; 5018 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 5019 return error::kOutOfBounds; 5020 } 5021 const GLuint* ids = GetSharedMemoryAs<const GLuint*>( 5022 c.ids_shm_id, c.ids_shm_offset, data_size); 5023 if (n < 0) { 5024 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0"); 5025 return error::kNoError; 5026 } 5027 if (ids == NULL) { 5028 return error::kOutOfBounds; 5029 } 5030 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids); 5031 return error::kNoError; 5032 } 5033 5034 void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM( 5035 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { 5036 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 5037 if (id_offset == 0) { 5038 for (GLsizei ii = 0; ii < n; ++ii) { 5039 ids[ii] = id_allocator->AllocateID(); 5040 } 5041 } else { 5042 for (GLsizei ii = 0; ii < n; ++ii) { 5043 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset); 5044 id_offset = ids[ii] + 1; 5045 } 5046 } 5047 } 5048 5049 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM( 5050 uint32 immediate_data_size, 5051 const void* cmd_data) { 5052 const gles2::cmds::GenSharedIdsCHROMIUM& c = 5053 *static_cast<const gles2::cmds::GenSharedIdsCHROMIUM*>(cmd_data); 5054 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 5055 GLuint id_offset = static_cast<GLuint>(c.id_offset); 5056 GLsizei n = static_cast<GLsizei>(c.n); 5057 uint32 data_size; 5058 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 5059 return error::kOutOfBounds; 5060 } 5061 GLuint* ids = GetSharedMemoryAs<GLuint*>( 5062 c.ids_shm_id, c.ids_shm_offset, data_size); 5063 if (n < 0) { 5064 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0"); 5065 return error::kNoError; 5066 } 5067 if (ids == NULL) { 5068 return error::kOutOfBounds; 5069 } 5070 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids); 5071 return error::kNoError; 5072 } 5073 5074 void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM( 5075 GLuint namespace_id, GLsizei n, const GLuint* ids) { 5076 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 5077 for (GLsizei ii = 0; ii < n; ++ii) { 5078 if (!id_allocator->MarkAsUsed(ids[ii])) { 5079 for (GLsizei jj = 0; jj < ii; ++jj) { 5080 id_allocator->FreeID(ids[jj]); 5081 } 5082 LOCAL_SET_GL_ERROR( 5083 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", 5084 "attempt to register id that already exists"); 5085 return; 5086 } 5087 } 5088 } 5089 5090 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM( 5091 uint32 immediate_data_size, 5092 const void* cmd_data) { 5093 const gles2::cmds::RegisterSharedIdsCHROMIUM& c = 5094 *static_cast<const gles2::cmds::RegisterSharedIdsCHROMIUM*>(cmd_data); 5095 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 5096 GLsizei n = static_cast<GLsizei>(c.n); 5097 uint32 data_size; 5098 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 5099 return error::kOutOfBounds; 5100 } 5101 GLuint* ids = GetSharedMemoryAs<GLuint*>( 5102 c.ids_shm_id, c.ids_shm_offset, data_size); 5103 if (n < 0) { 5104 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0"); 5105 return error::kNoError; 5106 } 5107 if (ids == NULL) { 5108 return error::kOutOfBounds; 5109 } 5110 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids); 5111 return error::kNoError; 5112 } 5113 5114 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { 5115 DCHECK(!ShouldDeferDraws()); 5116 if (CheckBoundFramebuffersValid("glClear")) { 5117 ApplyDirtyState(); 5118 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 5119 glClear(mask); 5120 } 5121 return error::kNoError; 5122 } 5123 5124 void GLES2DecoderImpl::DoFramebufferRenderbuffer( 5125 GLenum target, GLenum attachment, GLenum renderbuffertarget, 5126 GLuint client_renderbuffer_id) { 5127 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 5128 if (!framebuffer) { 5129 LOCAL_SET_GL_ERROR( 5130 GL_INVALID_OPERATION, 5131 "glFramebufferRenderbuffer", "no framebuffer bound"); 5132 return; 5133 } 5134 GLuint service_id = 0; 5135 Renderbuffer* renderbuffer = NULL; 5136 if (client_renderbuffer_id) { 5137 renderbuffer = GetRenderbuffer(client_renderbuffer_id); 5138 if (!renderbuffer) { 5139 LOCAL_SET_GL_ERROR( 5140 GL_INVALID_OPERATION, 5141 "glFramebufferRenderbuffer", "unknown renderbuffer"); 5142 return; 5143 } 5144 service_id = renderbuffer->service_id(); 5145 } 5146 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer"); 5147 glFramebufferRenderbufferEXT( 5148 target, attachment, renderbuffertarget, service_id); 5149 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer"); 5150 if (error == GL_NO_ERROR) { 5151 framebuffer->AttachRenderbuffer(attachment, renderbuffer); 5152 } 5153 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 5154 framebuffer_state_.clear_state_dirty = true; 5155 } 5156 OnFboChanged(); 5157 } 5158 5159 void GLES2DecoderImpl::DoDisable(GLenum cap) { 5160 if (SetCapabilityState(cap, false)) { 5161 glDisable(cap); 5162 } 5163 } 5164 5165 void GLES2DecoderImpl::DoEnable(GLenum cap) { 5166 if (SetCapabilityState(cap, true)) { 5167 glEnable(cap); 5168 } 5169 } 5170 5171 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { 5172 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); 5173 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); 5174 glDepthRange(znear, zfar); 5175 } 5176 5177 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) { 5178 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value)); 5179 state_.sample_coverage_invert = (invert != 0); 5180 glSampleCoverage(state_.sample_coverage_value, invert); 5181 } 5182 5183 // Assumes framebuffer is complete. 5184 void GLES2DecoderImpl::ClearUnclearedAttachments( 5185 GLenum target, Framebuffer* framebuffer) { 5186 if (target == GL_READ_FRAMEBUFFER_EXT) { 5187 // bind this to the DRAW point, clear then bind back to READ 5188 // TODO(gman): I don't think there is any guarantee that an FBO that 5189 // is complete on the READ attachment will be complete as a DRAW 5190 // attachment. 5191 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); 5192 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id()); 5193 } 5194 GLbitfield clear_bits = 0; 5195 if (framebuffer->HasUnclearedColorAttachments()) { 5196 glClearColor( 5197 0.0f, 0.0f, 0.0f, 5198 (GLES2Util::GetChannelsForFormat( 5199 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 5200 1.0f); 5201 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5202 clear_bits |= GL_COLOR_BUFFER_BIT; 5203 if (feature_info_->feature_flags().ext_draw_buffers) 5204 framebuffer->PrepareDrawBuffersForClear(); 5205 } 5206 5207 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || 5208 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 5209 glClearStencil(0); 5210 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); 5211 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); 5212 clear_bits |= GL_STENCIL_BUFFER_BIT; 5213 } 5214 5215 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || 5216 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 5217 glClearDepth(1.0f); 5218 state_.SetDeviceDepthMask(GL_TRUE); 5219 clear_bits |= GL_DEPTH_BUFFER_BIT; 5220 } 5221 5222 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5223 glClear(clear_bits); 5224 5225 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 && 5226 feature_info_->feature_flags().ext_draw_buffers) 5227 framebuffer->RestoreDrawBuffersAfterClear(); 5228 5229 framebuffer_manager()->MarkAttachmentsAsCleared( 5230 framebuffer, renderbuffer_manager(), texture_manager()); 5231 5232 RestoreClearState(); 5233 5234 if (target == GL_READ_FRAMEBUFFER_EXT) { 5235 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id()); 5236 Framebuffer* draw_framebuffer = 5237 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 5238 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : 5239 GetBackbufferServiceId(); 5240 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id); 5241 } 5242 } 5243 5244 void GLES2DecoderImpl::RestoreClearState() { 5245 framebuffer_state_.clear_state_dirty = true; 5246 glClearColor( 5247 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue, 5248 state_.color_clear_alpha); 5249 glClearStencil(state_.stencil_clear); 5250 glClearDepth(state_.depth_clear); 5251 if (state_.enable_flags.scissor_test) { 5252 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 5253 } 5254 } 5255 5256 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { 5257 Framebuffer* framebuffer = 5258 GetFramebufferInfoForTarget(target); 5259 if (!framebuffer) { 5260 return GL_FRAMEBUFFER_COMPLETE; 5261 } 5262 GLenum completeness = framebuffer->IsPossiblyComplete(); 5263 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 5264 return completeness; 5265 } 5266 return framebuffer->GetStatus(texture_manager(), target); 5267 } 5268 5269 void GLES2DecoderImpl::DoFramebufferTexture2D( 5270 GLenum target, GLenum attachment, GLenum textarget, 5271 GLuint client_texture_id, GLint level) { 5272 DoFramebufferTexture2DCommon( 5273 "glFramebufferTexture2D", target, attachment, 5274 textarget, client_texture_id, level, 0); 5275 } 5276 5277 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample( 5278 GLenum target, GLenum attachment, GLenum textarget, 5279 GLuint client_texture_id, GLint level, GLsizei samples) { 5280 DoFramebufferTexture2DCommon( 5281 "glFramebufferTexture2DMultisample", target, attachment, 5282 textarget, client_texture_id, level, samples); 5283 } 5284 5285 void GLES2DecoderImpl::DoFramebufferTexture2DCommon( 5286 const char* name, GLenum target, GLenum attachment, GLenum textarget, 5287 GLuint client_texture_id, GLint level, GLsizei samples) { 5288 if (samples > renderbuffer_manager()->max_samples()) { 5289 LOCAL_SET_GL_ERROR( 5290 GL_INVALID_VALUE, 5291 "glFramebufferTexture2DMultisample", "samples too large"); 5292 return; 5293 } 5294 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 5295 if (!framebuffer) { 5296 LOCAL_SET_GL_ERROR( 5297 GL_INVALID_OPERATION, 5298 name, "no framebuffer bound."); 5299 return; 5300 } 5301 GLuint service_id = 0; 5302 TextureRef* texture_ref = NULL; 5303 if (client_texture_id) { 5304 texture_ref = GetTexture(client_texture_id); 5305 if (!texture_ref) { 5306 LOCAL_SET_GL_ERROR( 5307 GL_INVALID_OPERATION, 5308 name, "unknown texture_ref"); 5309 return; 5310 } 5311 service_id = texture_ref->service_id(); 5312 } 5313 5314 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) { 5315 LOCAL_SET_GL_ERROR( 5316 GL_INVALID_VALUE, 5317 name, "level out of range"); 5318 return; 5319 } 5320 5321 if (texture_ref) 5322 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget); 5323 5324 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name); 5325 if (0 == samples) { 5326 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); 5327 } else { 5328 if (features().use_img_for_multisampled_render_to_texture) { 5329 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, 5330 service_id, level, samples); 5331 } else { 5332 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, 5333 service_id, level, samples); 5334 } 5335 } 5336 GLenum error = LOCAL_PEEK_GL_ERROR(name); 5337 if (error == GL_NO_ERROR) { 5338 framebuffer->AttachTexture(attachment, texture_ref, textarget, level, 5339 samples); 5340 } 5341 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 5342 framebuffer_state_.clear_state_dirty = true; 5343 } 5344 5345 if (texture_ref) 5346 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget); 5347 5348 OnFboChanged(); 5349 } 5350 5351 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( 5352 GLenum target, GLenum attachment, GLenum pname, GLint* params) { 5353 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 5354 if (!framebuffer) { 5355 LOCAL_SET_GL_ERROR( 5356 GL_INVALID_OPERATION, 5357 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound"); 5358 return; 5359 } 5360 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 5361 const Framebuffer::Attachment* attachment_object = 5362 framebuffer->GetAttachment(attachment); 5363 *params = attachment_object ? attachment_object->object_name() : 0; 5364 } else { 5365 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT && 5366 features().use_img_for_multisampled_render_to_texture) { 5367 pname = GL_TEXTURE_SAMPLES_IMG; 5368 } 5369 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); 5370 } 5371 } 5372 5373 void GLES2DecoderImpl::DoGetRenderbufferParameteriv( 5374 GLenum target, GLenum pname, GLint* params) { 5375 Renderbuffer* renderbuffer = 5376 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5377 if (!renderbuffer) { 5378 LOCAL_SET_GL_ERROR( 5379 GL_INVALID_OPERATION, 5380 "glGetRenderbufferParameteriv", "no renderbuffer bound"); 5381 return; 5382 } 5383 5384 EnsureRenderbufferBound(); 5385 switch (pname) { 5386 case GL_RENDERBUFFER_INTERNAL_FORMAT: 5387 *params = renderbuffer->internal_format(); 5388 break; 5389 case GL_RENDERBUFFER_WIDTH: 5390 *params = renderbuffer->width(); 5391 break; 5392 case GL_RENDERBUFFER_HEIGHT: 5393 *params = renderbuffer->height(); 5394 break; 5395 case GL_RENDERBUFFER_SAMPLES_EXT: 5396 if (features().use_img_for_multisampled_render_to_texture) { 5397 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG, 5398 params); 5399 } else { 5400 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT, 5401 params); 5402 } 5403 default: 5404 glGetRenderbufferParameterivEXT(target, pname, params); 5405 break; 5406 } 5407 } 5408 5409 void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( 5410 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 5411 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 5412 GLbitfield mask, GLenum filter) { 5413 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws()); 5414 5415 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) { 5416 return; 5417 } 5418 5419 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5420 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 5421 BlitFramebufferHelper( 5422 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5423 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, 5424 state_.enable_flags.scissor_test); 5425 } 5426 5427 void GLES2DecoderImpl::EnsureRenderbufferBound() { 5428 if (!state_.bound_renderbuffer_valid) { 5429 state_.bound_renderbuffer_valid = true; 5430 glBindRenderbufferEXT(GL_RENDERBUFFER, 5431 state_.bound_renderbuffer.get() 5432 ? state_.bound_renderbuffer->service_id() 5433 : 0); 5434 } 5435 } 5436 5437 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( 5438 const FeatureInfo* feature_info, 5439 GLenum target, 5440 GLsizei samples, 5441 GLenum internal_format, 5442 GLsizei width, 5443 GLsizei height) { 5444 // TODO(sievers): This could be resolved at the GL binding level, but the 5445 // binding process is currently a bit too 'brute force'. 5446 if (feature_info->feature_flags().is_angle) { 5447 glRenderbufferStorageMultisampleANGLE( 5448 target, samples, internal_format, width, height); 5449 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) { 5450 glRenderbufferStorageMultisample( 5451 target, samples, internal_format, width, height); 5452 } else { 5453 glRenderbufferStorageMultisampleEXT( 5454 target, samples, internal_format, width, height); 5455 } 5456 } 5457 5458 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, 5459 GLint srcY0, 5460 GLint srcX1, 5461 GLint srcY1, 5462 GLint dstX0, 5463 GLint dstY0, 5464 GLint dstX1, 5465 GLint dstY1, 5466 GLbitfield mask, 5467 GLenum filter) { 5468 // TODO(sievers): This could be resolved at the GL binding level, but the 5469 // binding process is currently a bit too 'brute force'. 5470 if (feature_info_->feature_flags().is_angle) { 5471 glBlitFramebufferANGLE( 5472 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5473 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) { 5474 glBlitFramebuffer( 5475 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5476 } else { 5477 glBlitFramebufferEXT( 5478 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5479 } 5480 } 5481 5482 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample( 5483 GLsizei samples, 5484 GLenum internalformat, 5485 GLsizei width, 5486 GLsizei height) { 5487 if (samples > renderbuffer_manager()->max_samples()) { 5488 LOCAL_SET_GL_ERROR( 5489 GL_INVALID_VALUE, 5490 "glRenderbufferStorageMultisample", "samples too large"); 5491 return false; 5492 } 5493 5494 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5495 height > renderbuffer_manager()->max_renderbuffer_size()) { 5496 LOCAL_SET_GL_ERROR( 5497 GL_INVALID_VALUE, 5498 "glRenderbufferStorageMultisample", "dimensions too large"); 5499 return false; 5500 } 5501 5502 uint32 estimated_size = 0; 5503 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize( 5504 width, height, samples, internalformat, &estimated_size)) { 5505 LOCAL_SET_GL_ERROR( 5506 GL_OUT_OF_MEMORY, 5507 "glRenderbufferStorageMultisample", "dimensions too large"); 5508 return false; 5509 } 5510 5511 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5512 LOCAL_SET_GL_ERROR( 5513 GL_OUT_OF_MEMORY, 5514 "glRenderbufferStorageMultisample", "out of memory"); 5515 return false; 5516 } 5517 5518 return true; 5519 } 5520 5521 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM( 5522 GLenum target, GLsizei samples, GLenum internalformat, 5523 GLsizei width, GLsizei height) { 5524 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5525 if (!renderbuffer) { 5526 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 5527 "glRenderbufferStorageMultisampleCHROMIUM", 5528 "no renderbuffer bound"); 5529 return; 5530 } 5531 5532 if (!ValidateRenderbufferStorageMultisample( 5533 samples, internalformat, width, height)) { 5534 return; 5535 } 5536 5537 EnsureRenderbufferBound(); 5538 GLenum impl_format = 5539 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5540 internalformat); 5541 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( 5542 "glRenderbufferStorageMultisampleCHROMIUM"); 5543 RenderbufferStorageMultisampleHelper( 5544 feature_info_.get(), target, samples, impl_format, width, height); 5545 GLenum error = 5546 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); 5547 if (error == GL_NO_ERROR) { 5548 5549 if (workarounds().validate_multisample_buffer_allocation) { 5550 if (!VerifyMultisampleRenderbufferIntegrity( 5551 renderbuffer->service_id(), impl_format)) { 5552 LOCAL_SET_GL_ERROR( 5553 GL_OUT_OF_MEMORY, 5554 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory"); 5555 return; 5556 } 5557 } 5558 5559 // TODO(gman): If renderbuffers tracked which framebuffers they were 5560 // attached to we could just mark those framebuffers as not complete. 5561 framebuffer_manager()->IncFramebufferStateChangeCount(); 5562 renderbuffer_manager()->SetInfo( 5563 renderbuffer, samples, internalformat, width, height); 5564 } 5565 } 5566 5567 // This is the handler for multisampled_render_to_texture extensions. 5568 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT( 5569 GLenum target, GLsizei samples, GLenum internalformat, 5570 GLsizei width, GLsizei height) { 5571 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5572 if (!renderbuffer) { 5573 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 5574 "glRenderbufferStorageMultisampleEXT", 5575 "no renderbuffer bound"); 5576 return; 5577 } 5578 5579 if (!ValidateRenderbufferStorageMultisample( 5580 samples, internalformat, width, height)) { 5581 return; 5582 } 5583 5584 EnsureRenderbufferBound(); 5585 GLenum impl_format = 5586 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5587 internalformat); 5588 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT"); 5589 if (features().use_img_for_multisampled_render_to_texture) { 5590 glRenderbufferStorageMultisampleIMG( 5591 target, samples, impl_format, width, height); 5592 } else { 5593 glRenderbufferStorageMultisampleEXT( 5594 target, samples, impl_format, width, height); 5595 } 5596 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT"); 5597 if (error == GL_NO_ERROR) { 5598 // TODO(gman): If renderbuffers tracked which framebuffers they were 5599 // attached to we could just mark those framebuffers as not complete. 5600 framebuffer_manager()->IncFramebufferStateChangeCount(); 5601 renderbuffer_manager()->SetInfo( 5602 renderbuffer, samples, internalformat, width, height); 5603 } 5604 } 5605 5606 // This function validates the allocation of a multisampled renderbuffer 5607 // by clearing it to a key color, blitting the contents to a texture, and 5608 // reading back the color to ensure it matches the key. 5609 bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( 5610 GLuint renderbuffer, GLenum format) { 5611 5612 // Only validate color buffers. 5613 // These formats have been selected because they are very common or are known 5614 // to be used by the WebGL backbuffer. If problems are observed with other 5615 // color formats they can be added here. 5616 switch(format) { 5617 case GL_RGB: 5618 case GL_RGB8: 5619 case GL_RGBA: 5620 case GL_RGBA8: 5621 break; 5622 default: 5623 return true; 5624 } 5625 5626 GLint draw_framebuffer, read_framebuffer; 5627 5628 // Cache framebuffer and texture bindings. 5629 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer); 5630 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); 5631 5632 if (!validation_texture_) { 5633 GLint bound_texture; 5634 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture); 5635 5636 // Create additional resources needed for the verification. 5637 glGenTextures(1, &validation_texture_); 5638 glGenFramebuffersEXT(1, &validation_fbo_multisample_); 5639 glGenFramebuffersEXT(1, &validation_fbo_); 5640 5641 // Texture only needs to be 1x1. 5642 glBindTexture(GL_TEXTURE_2D, validation_texture_); 5643 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, 5644 GL_UNSIGNED_BYTE, NULL); 5645 5646 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); 5647 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5648 GL_TEXTURE_2D, validation_texture_, 0); 5649 5650 glBindTexture(GL_TEXTURE_2D, bound_texture); 5651 } 5652 5653 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_); 5654 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5655 GL_RENDERBUFFER, renderbuffer); 5656 5657 // Cache current state and reset it to the values we require. 5658 GLboolean scissor_enabled = false; 5659 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled); 5660 if (scissor_enabled) 5661 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5662 5663 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; 5664 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); 5665 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5666 5667 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; 5668 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color); 5669 glClearColor(1.0f, 0.0f, 1.0f, 1.0f); 5670 5671 // Clear the buffer to the desired key color. 5672 glClear(GL_COLOR_BUFFER_BIT); 5673 5674 // Blit from the multisample buffer to a standard texture. 5675 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_); 5676 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_); 5677 5678 BlitFramebufferHelper( 5679 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); 5680 5681 // Read a pixel from the buffer. 5682 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); 5683 5684 unsigned char pixel[3] = {0, 0, 0}; 5685 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel); 5686 5687 // Detach the renderbuffer. 5688 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_); 5689 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5690 GL_RENDERBUFFER, 0); 5691 5692 // Restore cached state. 5693 if (scissor_enabled) 5694 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 5695 5696 state_.SetDeviceColorMask( 5697 color_mask[0], color_mask[1], color_mask[2], color_mask[3]); 5698 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); 5699 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer); 5700 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer); 5701 5702 // Return true if the pixel matched the desired key color. 5703 return (pixel[0] == 0xFF && 5704 pixel[1] == 0x00 && 5705 pixel[2] == 0xFF); 5706 } 5707 5708 void GLES2DecoderImpl::DoRenderbufferStorage( 5709 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 5710 Renderbuffer* renderbuffer = 5711 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5712 if (!renderbuffer) { 5713 LOCAL_SET_GL_ERROR( 5714 GL_INVALID_OPERATION, 5715 "glRenderbufferStorage", "no renderbuffer bound"); 5716 return; 5717 } 5718 5719 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5720 height > renderbuffer_manager()->max_renderbuffer_size()) { 5721 LOCAL_SET_GL_ERROR( 5722 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large"); 5723 return; 5724 } 5725 5726 uint32 estimated_size = 0; 5727 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize( 5728 width, height, 1, internalformat, &estimated_size)) { 5729 LOCAL_SET_GL_ERROR( 5730 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large"); 5731 return; 5732 } 5733 5734 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5735 LOCAL_SET_GL_ERROR( 5736 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); 5737 return; 5738 } 5739 5740 EnsureRenderbufferBound(); 5741 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage"); 5742 glRenderbufferStorageEXT( 5743 target, 5744 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5745 internalformat), 5746 width, 5747 height); 5748 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage"); 5749 if (error == GL_NO_ERROR) { 5750 // TODO(gman): If tetxures tracked which framebuffers they were attached to 5751 // we could just mark those framebuffers as not complete. 5752 framebuffer_manager()->IncFramebufferStateChangeCount(); 5753 renderbuffer_manager()->SetInfo( 5754 renderbuffer, 1, internalformat, width, height); 5755 } 5756 } 5757 5758 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { 5759 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram"); 5760 Program* program = GetProgramInfoNotShader( 5761 program_id, "glLinkProgram"); 5762 if (!program) { 5763 return; 5764 } 5765 5766 LogClientServiceForInfo(program, program_id, "glLinkProgram"); 5767 ShaderTranslator* vertex_translator = NULL; 5768 ShaderTranslator* fragment_translator = NULL; 5769 if (use_shader_translator_) { 5770 vertex_translator = vertex_translator_.get(); 5771 fragment_translator = fragment_translator_.get(); 5772 } 5773 if (program->Link(shader_manager(), 5774 vertex_translator, 5775 fragment_translator, 5776 workarounds().count_all_in_varyings_packing ? 5777 Program::kCountAll : Program::kCountOnlyStaticallyUsed, 5778 shader_cache_callback_)) { 5779 if (program == state_.current_program.get()) { 5780 if (workarounds().use_current_program_after_successful_link) 5781 glUseProgram(program->service_id()); 5782 if (workarounds().clear_uniforms_before_first_program_use) 5783 program_manager()->ClearUniforms(program); 5784 } 5785 } 5786 5787 // LinkProgram can be very slow. Exit command processing to allow for 5788 // context preemption and GPU watchdog checks. 5789 ExitCommandProcessingEarly(); 5790 }; 5791 5792 void GLES2DecoderImpl::DoTexParameterf( 5793 GLenum target, GLenum pname, GLfloat param) { 5794 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5795 &state_, target); 5796 if (!texture) { 5797 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture"); 5798 return; 5799 } 5800 5801 texture_manager()->SetParameterf( 5802 "glTexParameterf", GetErrorState(), texture, pname, param); 5803 } 5804 5805 void GLES2DecoderImpl::DoTexParameteri( 5806 GLenum target, GLenum pname, GLint param) { 5807 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5808 &state_, target); 5809 if (!texture) { 5810 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture"); 5811 return; 5812 } 5813 5814 texture_manager()->SetParameteri( 5815 "glTexParameteri", GetErrorState(), texture, pname, param); 5816 } 5817 5818 void GLES2DecoderImpl::DoTexParameterfv( 5819 GLenum target, GLenum pname, const GLfloat* params) { 5820 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5821 &state_, target); 5822 if (!texture) { 5823 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture"); 5824 return; 5825 } 5826 5827 texture_manager()->SetParameterf( 5828 "glTexParameterfv", GetErrorState(), texture, pname, *params); 5829 } 5830 5831 void GLES2DecoderImpl::DoTexParameteriv( 5832 GLenum target, GLenum pname, const GLint* params) { 5833 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5834 &state_, target); 5835 if (!texture) { 5836 LOCAL_SET_GL_ERROR( 5837 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture"); 5838 return; 5839 } 5840 5841 texture_manager()->SetParameteri( 5842 "glTexParameteriv", GetErrorState(), texture, pname, *params); 5843 } 5844 5845 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) { 5846 if (!state_.current_program.get()) { 5847 // The program does not exist. 5848 LOCAL_SET_GL_ERROR( 5849 GL_INVALID_OPERATION, function_name, "no program in use"); 5850 return false; 5851 } 5852 if (!state_.current_program->InUse()) { 5853 LOCAL_SET_GL_ERROR( 5854 GL_INVALID_OPERATION, function_name, "program not linked"); 5855 return false; 5856 } 5857 return true; 5858 } 5859 5860 bool GLES2DecoderImpl::CheckCurrentProgramForUniform( 5861 GLint location, const char* function_name) { 5862 if (!CheckCurrentProgram(function_name)) { 5863 return false; 5864 } 5865 return location != -1; 5866 } 5867 5868 bool GLES2DecoderImpl::PrepForSetUniformByLocation( 5869 GLint fake_location, 5870 const char* function_name, 5871 Program::UniformApiType api_type, 5872 GLint* real_location, 5873 GLenum* type, 5874 GLsizei* count) { 5875 DCHECK(type); 5876 DCHECK(count); 5877 DCHECK(real_location); 5878 5879 if (!CheckCurrentProgramForUniform(fake_location, function_name)) { 5880 return false; 5881 } 5882 GLint array_index = -1; 5883 const Program::UniformInfo* info = 5884 state_.current_program->GetUniformInfoByFakeLocation( 5885 fake_location, real_location, &array_index); 5886 if (!info) { 5887 LOCAL_SET_GL_ERROR( 5888 GL_INVALID_OPERATION, function_name, "unknown location"); 5889 return false; 5890 } 5891 5892 if ((api_type & info->accepts_api_type) == 0) { 5893 LOCAL_SET_GL_ERROR( 5894 GL_INVALID_OPERATION, function_name, 5895 "wrong uniform function for type"); 5896 return false; 5897 } 5898 if (*count > 1 && !info->is_array) { 5899 LOCAL_SET_GL_ERROR( 5900 GL_INVALID_OPERATION, function_name, "count > 1 for non-array"); 5901 return false; 5902 } 5903 *count = std::min(info->size - array_index, *count); 5904 if (*count <= 0) { 5905 return false; 5906 } 5907 *type = info->type; 5908 return true; 5909 } 5910 5911 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) { 5912 GLenum type = 0; 5913 GLsizei count = 1; 5914 GLint real_location = -1; 5915 if (!PrepForSetUniformByLocation(fake_location, 5916 "glUniform1i", 5917 Program::kUniform1i, 5918 &real_location, 5919 &type, 5920 &count)) { 5921 return; 5922 } 5923 if (!state_.current_program->SetSamplers( 5924 state_.texture_units.size(), fake_location, 1, &v0)) { 5925 LOCAL_SET_GL_ERROR( 5926 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range"); 5927 return; 5928 } 5929 glUniform1i(real_location, v0); 5930 } 5931 5932 void GLES2DecoderImpl::DoUniform1iv( 5933 GLint fake_location, GLsizei count, const GLint *value) { 5934 GLenum type = 0; 5935 GLint real_location = -1; 5936 if (!PrepForSetUniformByLocation(fake_location, 5937 "glUniform1iv", 5938 Program::kUniform1i, 5939 &real_location, 5940 &type, 5941 &count)) { 5942 return; 5943 } 5944 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB || 5945 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) { 5946 if (!state_.current_program->SetSamplers( 5947 state_.texture_units.size(), fake_location, count, value)) { 5948 LOCAL_SET_GL_ERROR( 5949 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range"); 5950 return; 5951 } 5952 } 5953 glUniform1iv(real_location, count, value); 5954 } 5955 5956 void GLES2DecoderImpl::DoUniform1fv( 5957 GLint fake_location, GLsizei count, const GLfloat* value) { 5958 GLenum type = 0; 5959 GLint real_location = -1; 5960 if (!PrepForSetUniformByLocation(fake_location, 5961 "glUniform1fv", 5962 Program::kUniform1f, 5963 &real_location, 5964 &type, 5965 &count)) { 5966 return; 5967 } 5968 if (type == GL_BOOL) { 5969 scoped_ptr<GLint[]> temp(new GLint[count]); 5970 for (GLsizei ii = 0; ii < count; ++ii) { 5971 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5972 } 5973 DoUniform1iv(real_location, count, temp.get()); 5974 } else { 5975 glUniform1fv(real_location, count, value); 5976 } 5977 } 5978 5979 void GLES2DecoderImpl::DoUniform2fv( 5980 GLint fake_location, GLsizei count, const GLfloat* value) { 5981 GLenum type = 0; 5982 GLint real_location = -1; 5983 if (!PrepForSetUniformByLocation(fake_location, 5984 "glUniform2fv", 5985 Program::kUniform2f, 5986 &real_location, 5987 &type, 5988 &count)) { 5989 return; 5990 } 5991 if (type == GL_BOOL_VEC2) { 5992 GLsizei num_values = count * 2; 5993 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5994 for (GLsizei ii = 0; ii < num_values; ++ii) { 5995 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5996 } 5997 glUniform2iv(real_location, count, temp.get()); 5998 } else { 5999 glUniform2fv(real_location, count, value); 6000 } 6001 } 6002 6003 void GLES2DecoderImpl::DoUniform3fv( 6004 GLint fake_location, GLsizei count, const GLfloat* value) { 6005 GLenum type = 0; 6006 GLint real_location = -1; 6007 if (!PrepForSetUniformByLocation(fake_location, 6008 "glUniform3fv", 6009 Program::kUniform3f, 6010 &real_location, 6011 &type, 6012 &count)) { 6013 return; 6014 } 6015 if (type == GL_BOOL_VEC3) { 6016 GLsizei num_values = count * 3; 6017 scoped_ptr<GLint[]> temp(new GLint[num_values]); 6018 for (GLsizei ii = 0; ii < num_values; ++ii) { 6019 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 6020 } 6021 glUniform3iv(real_location, count, temp.get()); 6022 } else { 6023 glUniform3fv(real_location, count, value); 6024 } 6025 } 6026 6027 void GLES2DecoderImpl::DoUniform4fv( 6028 GLint fake_location, GLsizei count, const GLfloat* value) { 6029 GLenum type = 0; 6030 GLint real_location = -1; 6031 if (!PrepForSetUniformByLocation(fake_location, 6032 "glUniform4fv", 6033 Program::kUniform4f, 6034 &real_location, 6035 &type, 6036 &count)) { 6037 return; 6038 } 6039 if (type == GL_BOOL_VEC4) { 6040 GLsizei num_values = count * 4; 6041 scoped_ptr<GLint[]> temp(new GLint[num_values]); 6042 for (GLsizei ii = 0; ii < num_values; ++ii) { 6043 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 6044 } 6045 glUniform4iv(real_location, count, temp.get()); 6046 } else { 6047 glUniform4fv(real_location, count, value); 6048 } 6049 } 6050 6051 void GLES2DecoderImpl::DoUniform2iv( 6052 GLint fake_location, GLsizei count, const GLint* value) { 6053 GLenum type = 0; 6054 GLint real_location = -1; 6055 if (!PrepForSetUniformByLocation(fake_location, 6056 "glUniform2iv", 6057 Program::kUniform2i, 6058 &real_location, 6059 &type, 6060 &count)) { 6061 return; 6062 } 6063 glUniform2iv(real_location, count, value); 6064 } 6065 6066 void GLES2DecoderImpl::DoUniform3iv( 6067 GLint fake_location, GLsizei count, const GLint* value) { 6068 GLenum type = 0; 6069 GLint real_location = -1; 6070 if (!PrepForSetUniformByLocation(fake_location, 6071 "glUniform3iv", 6072 Program::kUniform3i, 6073 &real_location, 6074 &type, 6075 &count)) { 6076 return; 6077 } 6078 glUniform3iv(real_location, count, value); 6079 } 6080 6081 void GLES2DecoderImpl::DoUniform4iv( 6082 GLint fake_location, GLsizei count, const GLint* value) { 6083 GLenum type = 0; 6084 GLint real_location = -1; 6085 if (!PrepForSetUniformByLocation(fake_location, 6086 "glUniform4iv", 6087 Program::kUniform4i, 6088 &real_location, 6089 &type, 6090 &count)) { 6091 return; 6092 } 6093 glUniform4iv(real_location, count, value); 6094 } 6095 6096 void GLES2DecoderImpl::DoUniformMatrix2fv( 6097 GLint fake_location, GLsizei count, GLboolean transpose, 6098 const GLfloat* value) { 6099 GLenum type = 0; 6100 GLint real_location = -1; 6101 if (!PrepForSetUniformByLocation(fake_location, 6102 "glUniformMatrix2fv", 6103 Program::kUniformMatrix2f, 6104 &real_location, 6105 &type, 6106 &count)) { 6107 return; 6108 } 6109 glUniformMatrix2fv(real_location, count, transpose, value); 6110 } 6111 6112 void GLES2DecoderImpl::DoUniformMatrix3fv( 6113 GLint fake_location, GLsizei count, GLboolean transpose, 6114 const GLfloat* value) { 6115 GLenum type = 0; 6116 GLint real_location = -1; 6117 if (!PrepForSetUniformByLocation(fake_location, 6118 "glUniformMatrix3fv", 6119 Program::kUniformMatrix3f, 6120 &real_location, 6121 &type, 6122 &count)) { 6123 return; 6124 } 6125 glUniformMatrix3fv(real_location, count, transpose, value); 6126 } 6127 6128 void GLES2DecoderImpl::DoUniformMatrix4fv( 6129 GLint fake_location, GLsizei count, GLboolean transpose, 6130 const GLfloat* value) { 6131 GLenum type = 0; 6132 GLint real_location = -1; 6133 if (!PrepForSetUniformByLocation(fake_location, 6134 "glUniformMatrix4fv", 6135 Program::kUniformMatrix4f, 6136 &real_location, 6137 &type, 6138 &count)) { 6139 return; 6140 } 6141 glUniformMatrix4fv(real_location, count, transpose, value); 6142 } 6143 6144 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { 6145 GLuint service_id = 0; 6146 Program* program = NULL; 6147 if (program_id) { 6148 program = GetProgramInfoNotShader(program_id, "glUseProgram"); 6149 if (!program) { 6150 return; 6151 } 6152 if (!program->IsValid()) { 6153 // Program was not linked successfully. (ie, glLinkProgram) 6154 LOCAL_SET_GL_ERROR( 6155 GL_INVALID_OPERATION, "glUseProgram", "program not linked"); 6156 return; 6157 } 6158 service_id = program->service_id(); 6159 } 6160 if (state_.current_program.get()) { 6161 program_manager()->UnuseProgram(shader_manager(), 6162 state_.current_program.get()); 6163 } 6164 state_.current_program = program; 6165 LogClientServiceMapping("glUseProgram", program_id, service_id); 6166 glUseProgram(service_id); 6167 if (state_.current_program.get()) { 6168 program_manager()->UseProgram(state_.current_program.get()); 6169 if (workarounds().clear_uniforms_before_first_program_use) 6170 program_manager()->ClearUniforms(program); 6171 } 6172 } 6173 6174 void GLES2DecoderImpl::RenderWarning( 6175 const char* filename, int line, const std::string& msg) { 6176 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg); 6177 } 6178 6179 void GLES2DecoderImpl::PerformanceWarning( 6180 const char* filename, int line, const std::string& msg) { 6181 logger_.LogMessage(filename, line, 6182 std::string("PERFORMANCE WARNING: ") + msg); 6183 } 6184 6185 void GLES2DecoderImpl::DoWillUseTexImageIfNeeded( 6186 Texture* texture, GLenum textarget) { 6187 // Image is already in use if texture is attached to a framebuffer. 6188 if (texture && !texture->IsAttachedToFramebuffer()) { 6189 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 6190 if (image) { 6191 ScopedGLErrorSuppressor suppressor( 6192 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded", 6193 GetErrorState()); 6194 glBindTexture(textarget, texture->service_id()); 6195 image->WillUseTexImage(); 6196 RestoreCurrentTextureBindings(&state_, textarget); 6197 } 6198 } 6199 } 6200 6201 void GLES2DecoderImpl::DoDidUseTexImageIfNeeded( 6202 Texture* texture, GLenum textarget) { 6203 // Image is still in use if texture is attached to a framebuffer. 6204 if (texture && !texture->IsAttachedToFramebuffer()) { 6205 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 6206 if (image) { 6207 ScopedGLErrorSuppressor suppressor( 6208 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded", 6209 GetErrorState()); 6210 glBindTexture(textarget, texture->service_id()); 6211 image->DidUseTexImage(); 6212 RestoreCurrentTextureBindings(&state_, textarget); 6213 } 6214 } 6215 } 6216 6217 bool GLES2DecoderImpl::PrepareTexturesForRender() { 6218 DCHECK(state_.current_program.get()); 6219 if (!texture_manager()->HaveUnrenderableTextures() && 6220 !texture_manager()->HaveImages()) { 6221 return true; 6222 } 6223 6224 bool textures_set = false; 6225 const Program::SamplerIndices& sampler_indices = 6226 state_.current_program->sampler_indices(); 6227 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6228 const Program::UniformInfo* uniform_info = 6229 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6230 DCHECK(uniform_info); 6231 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6232 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6233 if (texture_unit_index < state_.texture_units.size()) { 6234 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6235 TextureRef* texture_ref = 6236 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6237 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type); 6238 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 6239 textures_set = true; 6240 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6241 glBindTexture( 6242 textarget, 6243 texture_manager()->black_texture_id(uniform_info->type)); 6244 LOCAL_RENDER_WARNING( 6245 std::string("texture bound to texture unit ") + 6246 base::IntToString(texture_unit_index) + 6247 " is not renderable. It maybe non-power-of-2 and have" 6248 " incompatible texture filtering or is not" 6249 " 'texture complete'"); 6250 continue; 6251 } 6252 6253 if (textarget != GL_TEXTURE_CUBE_MAP) { 6254 Texture* texture = texture_ref->texture(); 6255 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 6256 if (image && !texture->IsAttachedToFramebuffer()) { 6257 ScopedGLErrorSuppressor suppressor( 6258 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState()); 6259 textures_set = true; 6260 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6261 image->WillUseTexImage(); 6262 continue; 6263 } 6264 } 6265 } 6266 // else: should this be an error? 6267 } 6268 } 6269 return !textures_set; 6270 } 6271 6272 void GLES2DecoderImpl::RestoreStateForTextures() { 6273 DCHECK(state_.current_program.get()); 6274 const Program::SamplerIndices& sampler_indices = 6275 state_.current_program->sampler_indices(); 6276 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6277 const Program::UniformInfo* uniform_info = 6278 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6279 DCHECK(uniform_info); 6280 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6281 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6282 if (texture_unit_index < state_.texture_units.size()) { 6283 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6284 TextureRef* texture_ref = 6285 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6286 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 6287 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6288 // Get the texture_ref info that was previously bound here. 6289 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D 6290 ? texture_unit.bound_texture_2d.get() 6291 : texture_unit.bound_texture_cube_map.get(); 6292 glBindTexture(texture_unit.bind_target, 6293 texture_ref ? texture_ref->service_id() : 0); 6294 continue; 6295 } 6296 6297 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) { 6298 Texture* texture = texture_ref->texture(); 6299 gfx::GLImage* image = 6300 texture->GetLevelImage(texture_unit.bind_target, 0); 6301 if (image && !texture->IsAttachedToFramebuffer()) { 6302 ScopedGLErrorSuppressor suppressor( 6303 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState()); 6304 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6305 image->DidUseTexImage(); 6306 continue; 6307 } 6308 } 6309 } 6310 } 6311 } 6312 // Set the active texture back to whatever the user had it as. 6313 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 6314 } 6315 6316 bool GLES2DecoderImpl::ClearUnclearedTextures() { 6317 // Only check if there are some uncleared textures. 6318 if (!texture_manager()->HaveUnsafeTextures()) { 6319 return true; 6320 } 6321 6322 // 1: Check all textures we are about to render with. 6323 if (state_.current_program.get()) { 6324 const Program::SamplerIndices& sampler_indices = 6325 state_.current_program->sampler_indices(); 6326 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6327 const Program::UniformInfo* uniform_info = 6328 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6329 DCHECK(uniform_info); 6330 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6331 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6332 if (texture_unit_index < state_.texture_units.size()) { 6333 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6334 TextureRef* texture_ref = 6335 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6336 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) { 6337 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) { 6338 return false; 6339 } 6340 } 6341 } 6342 } 6343 } 6344 } 6345 return true; 6346 } 6347 6348 bool GLES2DecoderImpl::IsDrawValid( 6349 const char* function_name, GLuint max_vertex_accessed, bool instanced, 6350 GLsizei primcount) { 6351 DCHECK(instanced || primcount == 1); 6352 6353 // NOTE: We specifically do not check current_program->IsValid() because 6354 // it could never be invalid since glUseProgram would have failed. While 6355 // glLinkProgram could later mark the program as invalid the previous 6356 // valid program will still function if it is still the current program. 6357 if (!state_.current_program.get()) { 6358 // The program does not exist. 6359 // But GL says no ERROR. 6360 LOCAL_RENDER_WARNING("Drawing with no current shader program."); 6361 return false; 6362 } 6363 6364 return state_.vertex_attrib_manager 6365 ->ValidateBindings(function_name, 6366 this, 6367 feature_info_.get(), 6368 state_.current_program.get(), 6369 max_vertex_accessed, 6370 instanced, 6371 primcount); 6372 } 6373 6374 bool GLES2DecoderImpl::SimulateAttrib0( 6375 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { 6376 DCHECK(simulated); 6377 *simulated = false; 6378 6379 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 6380 return true; 6381 6382 const VertexAttrib* attrib = 6383 state_.vertex_attrib_manager->GetVertexAttrib(0); 6384 // If it's enabled or it's not used then we don't need to do anything. 6385 bool attrib_0_used = 6386 state_.current_program->GetAttribInfoByLocation(0) != NULL; 6387 if (attrib->enabled() && attrib_0_used) { 6388 return true; 6389 } 6390 6391 // Make a buffer with a single repeated vec4 value enough to 6392 // simulate the constant value that is supposed to be here. 6393 // This is required to emulate GLES2 on GL. 6394 GLuint num_vertices = max_vertex_accessed + 1; 6395 uint32 size_needed = 0; 6396 6397 if (num_vertices == 0 || 6398 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) || 6399 size_needed > 0x7FFFFFFFU) { 6400 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6401 return false; 6402 } 6403 6404 LOCAL_PERFORMANCE_WARNING( 6405 "Attribute 0 is disabled. This has signficant performance penalty"); 6406 6407 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 6408 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 6409 6410 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_; 6411 if (new_buffer) { 6412 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 6413 GLenum error = glGetError(); 6414 if (error != GL_NO_ERROR) { 6415 LOCAL_SET_GL_ERROR( 6416 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6417 return false; 6418 } 6419 } 6420 6421 const Vec4& value = state_.attrib_values[0]; 6422 if (new_buffer || 6423 (attrib_0_used && 6424 (!attrib_0_buffer_matches_value_ || 6425 (value.v[0] != attrib_0_value_.v[0] || 6426 value.v[1] != attrib_0_value_.v[1] || 6427 value.v[2] != attrib_0_value_.v[2] || 6428 value.v[3] != attrib_0_value_.v[3])))) { 6429 std::vector<Vec4> temp(num_vertices, value); 6430 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); 6431 attrib_0_buffer_matches_value_ = true; 6432 attrib_0_value_ = value; 6433 attrib_0_size_ = size_needed; 6434 } 6435 6436 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); 6437 6438 if (attrib->divisor()) 6439 glVertexAttribDivisorANGLE(0, 0); 6440 6441 *simulated = true; 6442 return true; 6443 } 6444 6445 void GLES2DecoderImpl::RestoreStateForAttrib( 6446 GLuint attrib_index, bool restore_array_binding) { 6447 const VertexAttrib* attrib = 6448 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index); 6449 if (restore_array_binding) { 6450 const void* ptr = reinterpret_cast<const void*>(attrib->offset()); 6451 Buffer* buffer = attrib->buffer(); 6452 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0); 6453 glVertexAttribPointer( 6454 attrib_index, attrib->size(), attrib->type(), attrib->normalized(), 6455 attrib->gl_stride(), ptr); 6456 } 6457 if (attrib->divisor()) 6458 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor()); 6459 glBindBuffer( 6460 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ? 6461 state_.bound_array_buffer->service_id() : 0); 6462 6463 // Never touch vertex attribute 0's state (in particular, never 6464 // disable it) when running on desktop GL because it will never be 6465 // re-enabled. 6466 if (attrib_index != 0 || 6467 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 6468 if (attrib->enabled()) { 6469 glEnableVertexAttribArray(attrib_index); 6470 } else { 6471 glDisableVertexAttribArray(attrib_index); 6472 } 6473 } 6474 } 6475 6476 bool GLES2DecoderImpl::SimulateFixedAttribs( 6477 const char* function_name, 6478 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) { 6479 DCHECK(simulated); 6480 *simulated = false; 6481 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 6482 return true; 6483 6484 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) { 6485 return true; 6486 } 6487 6488 LOCAL_PERFORMANCE_WARNING( 6489 "GL_FIXED attributes have a signficant performance penalty"); 6490 6491 // NOTE: we could be smart and try to check if a buffer is used 6492 // twice in 2 different attribs, find the overlapping parts and therefore 6493 // duplicate the minimum amount of data but this whole code path is not meant 6494 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance 6495 // tests so we just add to the buffer attrib used. 6496 6497 GLuint elements_needed = 0; 6498 const VertexAttribManager::VertexAttribList& enabled_attribs = 6499 state_.vertex_attrib_manager->GetEnabledVertexAttribs(); 6500 for (VertexAttribManager::VertexAttribList::const_iterator it = 6501 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6502 const VertexAttrib* attrib = *it; 6503 const Program::VertexAttrib* attrib_info = 6504 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6505 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6506 max_vertex_accessed); 6507 GLuint num_vertices = max_accessed + 1; 6508 if (num_vertices == 0) { 6509 LOCAL_SET_GL_ERROR( 6510 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6511 return false; 6512 } 6513 if (attrib_info && 6514 attrib->CanAccess(max_accessed) && 6515 attrib->type() == GL_FIXED) { 6516 uint32 elements_used = 0; 6517 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) || 6518 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) { 6519 LOCAL_SET_GL_ERROR( 6520 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6521 return false; 6522 } 6523 } 6524 } 6525 6526 const uint32 kSizeOfFloat = sizeof(float); // NOLINT 6527 uint32 size_needed = 0; 6528 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) || 6529 size_needed > 0x7FFFFFFFU) { 6530 LOCAL_SET_GL_ERROR( 6531 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6532 return false; 6533 } 6534 6535 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 6536 6537 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); 6538 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) { 6539 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 6540 GLenum error = glGetError(); 6541 if (error != GL_NO_ERROR) { 6542 LOCAL_SET_GL_ERROR( 6543 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6544 return false; 6545 } 6546 } 6547 6548 // Copy the elements and convert to float 6549 GLintptr offset = 0; 6550 for (VertexAttribManager::VertexAttribList::const_iterator it = 6551 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6552 const VertexAttrib* attrib = *it; 6553 const Program::VertexAttrib* attrib_info = 6554 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6555 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6556 max_vertex_accessed); 6557 GLuint num_vertices = max_accessed + 1; 6558 if (num_vertices == 0) { 6559 LOCAL_SET_GL_ERROR( 6560 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6561 return false; 6562 } 6563 if (attrib_info && 6564 attrib->CanAccess(max_accessed) && 6565 attrib->type() == GL_FIXED) { 6566 int num_elements = attrib->size() * kSizeOfFloat; 6567 int size = num_elements * num_vertices; 6568 scoped_ptr<float[]> data(new float[size]); 6569 const int32* src = reinterpret_cast<const int32 *>( 6570 attrib->buffer()->GetRange(attrib->offset(), size)); 6571 const int32* end = src + num_elements; 6572 float* dst = data.get(); 6573 while (src != end) { 6574 *dst++ = static_cast<float>(*src++) / 65536.0f; 6575 } 6576 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get()); 6577 glVertexAttribPointer( 6578 attrib->index(), attrib->size(), GL_FLOAT, false, 0, 6579 reinterpret_cast<GLvoid*>(offset)); 6580 offset += size; 6581 } 6582 } 6583 *simulated = true; 6584 return true; 6585 } 6586 6587 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() { 6588 // There's no need to call glVertexAttribPointer because we shadow all the 6589 // settings and passing GL_FIXED to it will not work. 6590 glBindBuffer( 6591 GL_ARRAY_BUFFER, 6592 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id() 6593 : 0); 6594 } 6595 6596 error::Error GLES2DecoderImpl::DoDrawArrays( 6597 const char* function_name, 6598 bool instanced, 6599 GLenum mode, 6600 GLint first, 6601 GLsizei count, 6602 GLsizei primcount) { 6603 error::Error error = WillAccessBoundFramebufferForDraw(); 6604 if (error != error::kNoError) 6605 return error; 6606 if (!validators_->draw_mode.IsValid(mode)) { 6607 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6608 return error::kNoError; 6609 } 6610 if (count < 0) { 6611 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6612 return error::kNoError; 6613 } 6614 if (primcount < 0) { 6615 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6616 return error::kNoError; 6617 } 6618 if (!CheckBoundFramebuffersValid(function_name)) { 6619 return error::kNoError; 6620 } 6621 // We have to check this here because the prototype for glDrawArrays 6622 // is GLint not GLsizei. 6623 if (first < 0) { 6624 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0"); 6625 return error::kNoError; 6626 } 6627 6628 if (count == 0 || primcount == 0) { 6629 LOCAL_RENDER_WARNING("Render count or primcount is 0."); 6630 return error::kNoError; 6631 } 6632 6633 GLuint max_vertex_accessed = first + count - 1; 6634 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) { 6635 if (!ClearUnclearedTextures()) { 6636 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6637 return error::kNoError; 6638 } 6639 bool simulated_attrib_0 = false; 6640 if (!SimulateAttrib0( 6641 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6642 return error::kNoError; 6643 } 6644 bool simulated_fixed_attribs = false; 6645 if (SimulateFixedAttribs( 6646 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6647 primcount)) { 6648 bool textures_set = !PrepareTexturesForRender(); 6649 ApplyDirtyState(); 6650 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 6651 if (!instanced) { 6652 glDrawArrays(mode, first, count); 6653 } else { 6654 glDrawArraysInstancedANGLE(mode, first, count, primcount); 6655 } 6656 if (textures_set) { 6657 RestoreStateForTextures(); 6658 } 6659 if (simulated_fixed_attribs) { 6660 RestoreStateForSimulatedFixedAttribs(); 6661 } 6662 } 6663 if (simulated_attrib_0) { 6664 // We don't have to restore attrib 0 generic data at the end of this 6665 // function even if it is simulated. This is because we will simulate 6666 // it in each draw call, and attrib 0 generic data queries use cached 6667 // values instead of passing down to the underlying driver. 6668 RestoreStateForAttrib(0, false); 6669 } 6670 } 6671 return error::kNoError; 6672 } 6673 6674 error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size, 6675 const void* cmd_data) { 6676 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data); 6677 return DoDrawArrays("glDrawArrays", 6678 false, 6679 static_cast<GLenum>(c.mode), 6680 static_cast<GLint>(c.first), 6681 static_cast<GLsizei>(c.count), 6682 1); 6683 } 6684 6685 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( 6686 uint32 immediate_data_size, 6687 const void* cmd_data) { 6688 const gles2::cmds::DrawArraysInstancedANGLE& c = 6689 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data); 6690 if (!features().angle_instanced_arrays) { 6691 LOCAL_SET_GL_ERROR( 6692 GL_INVALID_OPERATION, 6693 "glDrawArraysInstancedANGLE", "function not available"); 6694 return error::kNoError; 6695 } 6696 return DoDrawArrays("glDrawArraysIntancedANGLE", 6697 true, 6698 static_cast<GLenum>(c.mode), 6699 static_cast<GLint>(c.first), 6700 static_cast<GLsizei>(c.count), 6701 static_cast<GLsizei>(c.primcount)); 6702 } 6703 6704 error::Error GLES2DecoderImpl::DoDrawElements( 6705 const char* function_name, 6706 bool instanced, 6707 GLenum mode, 6708 GLsizei count, 6709 GLenum type, 6710 int32 offset, 6711 GLsizei primcount) { 6712 error::Error error = WillAccessBoundFramebufferForDraw(); 6713 if (error != error::kNoError) 6714 return error; 6715 if (!state_.vertex_attrib_manager->element_array_buffer()) { 6716 LOCAL_SET_GL_ERROR( 6717 GL_INVALID_OPERATION, function_name, "No element array buffer bound"); 6718 return error::kNoError; 6719 } 6720 6721 if (count < 0) { 6722 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6723 return error::kNoError; 6724 } 6725 if (offset < 0) { 6726 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0"); 6727 return error::kNoError; 6728 } 6729 if (!validators_->draw_mode.IsValid(mode)) { 6730 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6731 return error::kNoError; 6732 } 6733 if (!validators_->index_type.IsValid(type)) { 6734 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type"); 6735 return error::kNoError; 6736 } 6737 if (primcount < 0) { 6738 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6739 return error::kNoError; 6740 } 6741 6742 if (!CheckBoundFramebuffersValid(function_name)) { 6743 return error::kNoError; 6744 } 6745 6746 if (count == 0 || primcount == 0) { 6747 return error::kNoError; 6748 } 6749 6750 GLuint max_vertex_accessed; 6751 Buffer* element_array_buffer = 6752 state_.vertex_attrib_manager->element_array_buffer(); 6753 6754 if (!element_array_buffer->GetMaxValueForRange( 6755 offset, count, type, &max_vertex_accessed)) { 6756 LOCAL_SET_GL_ERROR( 6757 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); 6758 return error::kNoError; 6759 } 6760 6761 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) { 6762 if (!ClearUnclearedTextures()) { 6763 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6764 return error::kNoError; 6765 } 6766 bool simulated_attrib_0 = false; 6767 if (!SimulateAttrib0( 6768 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6769 return error::kNoError; 6770 } 6771 bool simulated_fixed_attribs = false; 6772 if (SimulateFixedAttribs( 6773 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6774 primcount)) { 6775 bool textures_set = !PrepareTexturesForRender(); 6776 ApplyDirtyState(); 6777 // TODO(gman): Refactor to hide these details in BufferManager or 6778 // VertexAttribManager. 6779 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 6780 bool used_client_side_array = false; 6781 if (element_array_buffer->IsClientSideArray()) { 6782 used_client_side_array = true; 6783 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 6784 indices = element_array_buffer->GetRange(offset, 0); 6785 } 6786 6787 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 6788 if (!instanced) { 6789 glDrawElements(mode, count, type, indices); 6790 } else { 6791 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 6792 } 6793 6794 if (used_client_side_array) { 6795 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 6796 element_array_buffer->service_id()); 6797 } 6798 6799 if (textures_set) { 6800 RestoreStateForTextures(); 6801 } 6802 if (simulated_fixed_attribs) { 6803 RestoreStateForSimulatedFixedAttribs(); 6804 } 6805 } 6806 if (simulated_attrib_0) { 6807 // We don't have to restore attrib 0 generic data at the end of this 6808 // function even if it is simulated. This is because we will simulate 6809 // it in each draw call, and attrib 0 generic data queries use cached 6810 // values instead of passing down to the underlying driver. 6811 RestoreStateForAttrib(0, false); 6812 } 6813 } 6814 return error::kNoError; 6815 } 6816 6817 error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size, 6818 const void* cmd_data) { 6819 const gles2::cmds::DrawElements& c = 6820 *static_cast<const gles2::cmds::DrawElements*>(cmd_data); 6821 return DoDrawElements("glDrawElements", 6822 false, 6823 static_cast<GLenum>(c.mode), 6824 static_cast<GLsizei>(c.count), 6825 static_cast<GLenum>(c.type), 6826 static_cast<int32>(c.index_offset), 6827 1); 6828 } 6829 6830 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( 6831 uint32 immediate_data_size, 6832 const void* cmd_data) { 6833 const gles2::cmds::DrawElementsInstancedANGLE& c = 6834 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data); 6835 if (!features().angle_instanced_arrays) { 6836 LOCAL_SET_GL_ERROR( 6837 GL_INVALID_OPERATION, 6838 "glDrawElementsInstancedANGLE", "function not available"); 6839 return error::kNoError; 6840 } 6841 return DoDrawElements("glDrawElementsInstancedANGLE", 6842 true, 6843 static_cast<GLenum>(c.mode), 6844 static_cast<GLsizei>(c.count), 6845 static_cast<GLenum>(c.type), 6846 static_cast<int32>(c.index_offset), 6847 static_cast<GLsizei>(c.primcount)); 6848 } 6849 6850 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( 6851 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { 6852 GLuint max_vertex_accessed = 0; 6853 Buffer* buffer = GetBuffer(buffer_id); 6854 if (!buffer) { 6855 // TODO(gman): Should this be a GL error or a command buffer error? 6856 LOCAL_SET_GL_ERROR( 6857 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer"); 6858 } else { 6859 if (!buffer->GetMaxValueForRange( 6860 offset, count, type, &max_vertex_accessed)) { 6861 // TODO(gman): Should this be a GL error or a command buffer error? 6862 LOCAL_SET_GL_ERROR( 6863 GL_INVALID_OPERATION, 6864 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); 6865 } 6866 } 6867 return max_vertex_accessed; 6868 } 6869 6870 // Calls glShaderSource for the various versions of the ShaderSource command. 6871 // Assumes that data / data_size points to a piece of memory that is in range 6872 // of whatever context it came from (shared memory, immediate memory, bucket 6873 // memory.) 6874 error::Error GLES2DecoderImpl::ShaderSourceHelper( 6875 GLuint client_id, const char* data, uint32 data_size) { 6876 std::string str(data, data + data_size); 6877 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource"); 6878 if (!shader) { 6879 return error::kNoError; 6880 } 6881 // Note: We don't actually call glShaderSource here. We wait until 6882 // the call to glCompileShader. 6883 shader->set_source(str); 6884 return error::kNoError; 6885 } 6886 6887 error::Error GLES2DecoderImpl::HandleShaderSourceBucket( 6888 uint32 immediate_data_size, 6889 const void* cmd_data) { 6890 const gles2::cmds::ShaderSourceBucket& c = 6891 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data); 6892 Bucket* bucket = GetBucket(c.data_bucket_id); 6893 if (!bucket || bucket->size() == 0) { 6894 return error::kInvalidArguments; 6895 } 6896 return ShaderSourceHelper( 6897 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1), 6898 bucket->size() - 1); 6899 } 6900 6901 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { 6902 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader"); 6903 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader"); 6904 if (!shader) { 6905 return; 6906 } 6907 ShaderTranslator* translator = NULL; 6908 if (use_shader_translator_) { 6909 translator = shader->shader_type() == GL_VERTEX_SHADER ? 6910 vertex_translator_.get() : fragment_translator_.get(); 6911 } 6912 6913 shader->DoCompile( 6914 translator, 6915 feature_info_->feature_flags().angle_translated_shader_source ? 6916 Shader::kANGLE : Shader::kGL); 6917 6918 // CompileShader can be very slow. Exit command processing to allow for 6919 // context preemption and GPU watchdog checks. 6920 ExitCommandProcessingEarly(); 6921 } 6922 6923 void GLES2DecoderImpl::DoGetShaderiv( 6924 GLuint shader_id, GLenum pname, GLint* params) { 6925 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv"); 6926 if (!shader) { 6927 return; 6928 } 6929 switch (pname) { 6930 case GL_SHADER_SOURCE_LENGTH: 6931 *params = shader->source().size(); 6932 if (*params) 6933 ++(*params); 6934 return; 6935 case GL_COMPILE_STATUS: 6936 *params = compile_shader_always_succeeds_ ? true : shader->valid(); 6937 return; 6938 case GL_INFO_LOG_LENGTH: 6939 *params = shader->log_info().size(); 6940 if (*params) 6941 ++(*params); 6942 return; 6943 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 6944 *params = shader->translated_source().size(); 6945 if (*params) 6946 ++(*params); 6947 return; 6948 default: 6949 break; 6950 } 6951 glGetShaderiv(shader->service_id(), pname, params); 6952 } 6953 6954 error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size, 6955 const void* cmd_data) { 6956 const gles2::cmds::GetShaderSource& c = 6957 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data); 6958 GLuint shader_id = c.shader; 6959 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6960 Bucket* bucket = CreateBucket(bucket_id); 6961 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource"); 6962 if (!shader || shader->source().empty()) { 6963 bucket->SetSize(0); 6964 return error::kNoError; 6965 } 6966 bucket->SetFromString(shader->source().c_str()); 6967 return error::kNoError; 6968 } 6969 6970 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( 6971 uint32 immediate_data_size, 6972 const void* cmd_data) { 6973 const gles2::cmds::GetTranslatedShaderSourceANGLE& c = 6974 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>( 6975 cmd_data); 6976 GLuint shader_id = c.shader; 6977 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6978 Bucket* bucket = CreateBucket(bucket_id); 6979 Shader* shader = GetShaderInfoNotProgram( 6980 shader_id, "glGetTranslatedShaderSourceANGLE"); 6981 if (!shader) { 6982 bucket->SetSize(0); 6983 return error::kNoError; 6984 } 6985 6986 bucket->SetFromString(shader->translated_source().c_str()); 6987 return error::kNoError; 6988 } 6989 6990 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( 6991 uint32 immediate_data_size, 6992 const void* cmd_data) { 6993 const gles2::cmds::GetProgramInfoLog& c = 6994 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data); 6995 GLuint program_id = c.program; 6996 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6997 Bucket* bucket = CreateBucket(bucket_id); 6998 Program* program = GetProgramInfoNotShader( 6999 program_id, "glGetProgramInfoLog"); 7000 if (!program || !program->log_info()) { 7001 bucket->SetFromString(""); 7002 return error::kNoError; 7003 } 7004 bucket->SetFromString(program->log_info()->c_str()); 7005 return error::kNoError; 7006 } 7007 7008 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( 7009 uint32 immediate_data_size, 7010 const void* cmd_data) { 7011 const gles2::cmds::GetShaderInfoLog& c = 7012 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data); 7013 GLuint shader_id = c.shader; 7014 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 7015 Bucket* bucket = CreateBucket(bucket_id); 7016 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog"); 7017 if (!shader) { 7018 bucket->SetFromString(""); 7019 return error::kNoError; 7020 } 7021 bucket->SetFromString(shader->log_info().c_str()); 7022 return error::kNoError; 7023 } 7024 7025 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { 7026 return state_.GetEnabled(cap); 7027 } 7028 7029 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { 7030 const Buffer* buffer = GetBuffer(client_id); 7031 return buffer && buffer->IsValid() && !buffer->IsDeleted(); 7032 } 7033 7034 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) { 7035 const Framebuffer* framebuffer = 7036 GetFramebuffer(client_id); 7037 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted(); 7038 } 7039 7040 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) { 7041 // IsProgram is true for programs as soon as they are created, until they are 7042 // deleted and no longer in use. 7043 const Program* program = GetProgram(client_id); 7044 return program != NULL && !program->IsDeleted(); 7045 } 7046 7047 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) { 7048 const Renderbuffer* renderbuffer = 7049 GetRenderbuffer(client_id); 7050 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted(); 7051 } 7052 7053 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) { 7054 // IsShader is true for shaders as soon as they are created, until they 7055 // are deleted and not attached to any programs. 7056 const Shader* shader = GetShader(client_id); 7057 return shader != NULL && !shader->IsDeleted(); 7058 } 7059 7060 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { 7061 const TextureRef* texture_ref = GetTexture(client_id); 7062 return texture_ref && texture_ref->texture()->IsValid(); 7063 } 7064 7065 void GLES2DecoderImpl::DoAttachShader( 7066 GLuint program_client_id, GLint shader_client_id) { 7067 Program* program = GetProgramInfoNotShader( 7068 program_client_id, "glAttachShader"); 7069 if (!program) { 7070 return; 7071 } 7072 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader"); 7073 if (!shader) { 7074 return; 7075 } 7076 if (!program->AttachShader(shader_manager(), shader)) { 7077 LOCAL_SET_GL_ERROR( 7078 GL_INVALID_OPERATION, 7079 "glAttachShader", 7080 "can not attach more than one shader of the same type."); 7081 return; 7082 } 7083 glAttachShader(program->service_id(), shader->service_id()); 7084 } 7085 7086 void GLES2DecoderImpl::DoDetachShader( 7087 GLuint program_client_id, GLint shader_client_id) { 7088 Program* program = GetProgramInfoNotShader( 7089 program_client_id, "glDetachShader"); 7090 if (!program) { 7091 return; 7092 } 7093 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader"); 7094 if (!shader) { 7095 return; 7096 } 7097 if (!program->DetachShader(shader_manager(), shader)) { 7098 LOCAL_SET_GL_ERROR( 7099 GL_INVALID_OPERATION, 7100 "glDetachShader", "shader not attached to program"); 7101 return; 7102 } 7103 glDetachShader(program->service_id(), shader->service_id()); 7104 } 7105 7106 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { 7107 Program* program = GetProgramInfoNotShader( 7108 program_client_id, "glValidateProgram"); 7109 if (!program) { 7110 return; 7111 } 7112 program->Validate(); 7113 } 7114 7115 void GLES2DecoderImpl::GetVertexAttribHelper( 7116 const VertexAttrib* attrib, GLenum pname, GLint* params) { 7117 switch (pname) { 7118 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 7119 Buffer* buffer = attrib->buffer(); 7120 if (buffer && !buffer->IsDeleted()) { 7121 GLuint client_id; 7122 buffer_manager()->GetClientId(buffer->service_id(), &client_id); 7123 *params = client_id; 7124 } 7125 break; 7126 } 7127 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 7128 *params = attrib->enabled(); 7129 break; 7130 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 7131 *params = attrib->size(); 7132 break; 7133 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 7134 *params = attrib->gl_stride(); 7135 break; 7136 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 7137 *params = attrib->type(); 7138 break; 7139 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 7140 *params = attrib->normalized(); 7141 break; 7142 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 7143 *params = attrib->divisor(); 7144 break; 7145 default: 7146 NOTREACHED(); 7147 break; 7148 } 7149 } 7150 7151 void GLES2DecoderImpl::DoGetTexParameterfv( 7152 GLenum target, GLenum pname, GLfloat* params) { 7153 InitTextureMaxAnisotropyIfNeeded(target, pname); 7154 glGetTexParameterfv(target, pname, params); 7155 } 7156 7157 void GLES2DecoderImpl::DoGetTexParameteriv( 7158 GLenum target, GLenum pname, GLint* params) { 7159 InitTextureMaxAnisotropyIfNeeded(target, pname); 7160 glGetTexParameteriv(target, pname, params); 7161 } 7162 7163 void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded( 7164 GLenum target, GLenum pname) { 7165 if (!workarounds().init_texture_max_anisotropy) 7166 return; 7167 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT || 7168 !validators_->texture_parameter.IsValid(pname)) { 7169 return; 7170 } 7171 7172 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 7173 &state_, target); 7174 if (!texture_ref) { 7175 LOCAL_SET_GL_ERROR( 7176 GL_INVALID_OPERATION, 7177 "glGetTexParamter{fi}v", "unknown texture for target"); 7178 return; 7179 } 7180 Texture* texture = texture_ref->texture(); 7181 texture->InitTextureMaxAnisotropyIfNeeded(target); 7182 } 7183 7184 void GLES2DecoderImpl::DoGetVertexAttribfv( 7185 GLuint index, GLenum pname, GLfloat* params) { 7186 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 7187 if (!attrib) { 7188 LOCAL_SET_GL_ERROR( 7189 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range"); 7190 return; 7191 } 7192 switch (pname) { 7193 case GL_CURRENT_VERTEX_ATTRIB: { 7194 const Vec4& value = state_.attrib_values[index]; 7195 params[0] = value.v[0]; 7196 params[1] = value.v[1]; 7197 params[2] = value.v[2]; 7198 params[3] = value.v[3]; 7199 break; 7200 } 7201 default: { 7202 GLint value = 0; 7203 GetVertexAttribHelper(attrib, pname, &value); 7204 *params = static_cast<GLfloat>(value); 7205 break; 7206 } 7207 } 7208 } 7209 7210 void GLES2DecoderImpl::DoGetVertexAttribiv( 7211 GLuint index, GLenum pname, GLint* params) { 7212 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 7213 if (!attrib) { 7214 LOCAL_SET_GL_ERROR( 7215 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range"); 7216 return; 7217 } 7218 switch (pname) { 7219 case GL_CURRENT_VERTEX_ATTRIB: { 7220 const Vec4& value = state_.attrib_values[index]; 7221 params[0] = static_cast<GLint>(value.v[0]); 7222 params[1] = static_cast<GLint>(value.v[1]); 7223 params[2] = static_cast<GLint>(value.v[2]); 7224 params[3] = static_cast<GLint>(value.v[3]); 7225 break; 7226 } 7227 default: 7228 GetVertexAttribHelper(attrib, pname, params); 7229 break; 7230 } 7231 } 7232 7233 bool GLES2DecoderImpl::SetVertexAttribValue( 7234 const char* function_name, GLuint index, const GLfloat* value) { 7235 if (index >= state_.attrib_values.size()) { 7236 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range"); 7237 return false; 7238 } 7239 Vec4& v = state_.attrib_values[index]; 7240 v.v[0] = value[0]; 7241 v.v[1] = value[1]; 7242 v.v[2] = value[2]; 7243 v.v[3] = value[3]; 7244 return true; 7245 } 7246 7247 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) { 7248 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, }; 7249 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) { 7250 glVertexAttrib1f(index, v0); 7251 } 7252 } 7253 7254 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) { 7255 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, }; 7256 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) { 7257 glVertexAttrib2f(index, v0, v1); 7258 } 7259 } 7260 7261 void GLES2DecoderImpl::DoVertexAttrib3f( 7262 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) { 7263 GLfloat v[4] = { v0, v1, v2, 1.0f, }; 7264 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) { 7265 glVertexAttrib3f(index, v0, v1, v2); 7266 } 7267 } 7268 7269 void GLES2DecoderImpl::DoVertexAttrib4f( 7270 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { 7271 GLfloat v[4] = { v0, v1, v2, v3, }; 7272 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) { 7273 glVertexAttrib4f(index, v0, v1, v2, v3); 7274 } 7275 } 7276 7277 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) { 7278 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, }; 7279 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) { 7280 glVertexAttrib1fv(index, v); 7281 } 7282 } 7283 7284 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) { 7285 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, }; 7286 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) { 7287 glVertexAttrib2fv(index, v); 7288 } 7289 } 7290 7291 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) { 7292 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, }; 7293 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) { 7294 glVertexAttrib3fv(index, v); 7295 } 7296 } 7297 7298 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) { 7299 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) { 7300 glVertexAttrib4fv(index, v); 7301 } 7302 } 7303 7304 error::Error GLES2DecoderImpl::HandleVertexAttribPointer( 7305 uint32 immediate_data_size, 7306 const void* cmd_data) { 7307 const gles2::cmds::VertexAttribPointer& c = 7308 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data); 7309 7310 if (!state_.bound_array_buffer.get() || 7311 state_.bound_array_buffer->IsDeleted()) { 7312 if (state_.vertex_attrib_manager.get() == 7313 state_.default_vertex_attrib_manager.get()) { 7314 LOCAL_SET_GL_ERROR( 7315 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound"); 7316 return error::kNoError; 7317 } else if (c.offset != 0) { 7318 LOCAL_SET_GL_ERROR( 7319 GL_INVALID_VALUE, 7320 "glVertexAttribPointer", "client side arrays are not allowed"); 7321 return error::kNoError; 7322 } 7323 } 7324 7325 GLuint indx = c.indx; 7326 GLint size = c.size; 7327 GLenum type = c.type; 7328 GLboolean normalized = c.normalized; 7329 GLsizei stride = c.stride; 7330 GLsizei offset = c.offset; 7331 const void* ptr = reinterpret_cast<const void*>(offset); 7332 if (!validators_->vertex_attrib_type.IsValid(type)) { 7333 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type"); 7334 return error::kNoError; 7335 } 7336 if (!validators_->vertex_attrib_size.IsValid(size)) { 7337 LOCAL_SET_GL_ERROR( 7338 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE"); 7339 return error::kNoError; 7340 } 7341 if (indx >= group_->max_vertex_attribs()) { 7342 LOCAL_SET_GL_ERROR( 7343 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range"); 7344 return error::kNoError; 7345 } 7346 if (stride < 0) { 7347 LOCAL_SET_GL_ERROR( 7348 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0"); 7349 return error::kNoError; 7350 } 7351 if (stride > 255) { 7352 LOCAL_SET_GL_ERROR( 7353 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255"); 7354 return error::kNoError; 7355 } 7356 if (offset < 0) { 7357 LOCAL_SET_GL_ERROR( 7358 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0"); 7359 return error::kNoError; 7360 } 7361 GLsizei component_size = 7362 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); 7363 // component_size must be a power of two to use & as optimized modulo. 7364 DCHECK(GLES2Util::IsPOT(component_size)); 7365 if (offset & (component_size - 1)) { 7366 LOCAL_SET_GL_ERROR( 7367 GL_INVALID_OPERATION, 7368 "glVertexAttribPointer", "offset not valid for type"); 7369 return error::kNoError; 7370 } 7371 if (stride & (component_size - 1)) { 7372 LOCAL_SET_GL_ERROR( 7373 GL_INVALID_OPERATION, 7374 "glVertexAttribPointer", "stride not valid for type"); 7375 return error::kNoError; 7376 } 7377 state_.vertex_attrib_manager 7378 ->SetAttribInfo(indx, 7379 state_.bound_array_buffer.get(), 7380 size, 7381 type, 7382 normalized, 7383 stride, 7384 stride != 0 ? stride : component_size * size, 7385 offset); 7386 if (type != GL_FIXED) { 7387 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); 7388 } 7389 return error::kNoError; 7390 } 7391 7392 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, 7393 GLsizei height) { 7394 state_.viewport_x = x; 7395 state_.viewport_y = y; 7396 state_.viewport_width = std::min(width, viewport_max_width_); 7397 state_.viewport_height = std::min(height, viewport_max_height_); 7398 glViewport(x, y, width, height); 7399 } 7400 7401 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( 7402 uint32 immediate_data_size, 7403 const void* cmd_data) { 7404 const gles2::cmds::VertexAttribDivisorANGLE& c = 7405 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data); 7406 if (!features().angle_instanced_arrays) { 7407 LOCAL_SET_GL_ERROR( 7408 GL_INVALID_OPERATION, 7409 "glVertexAttribDivisorANGLE", "function not available"); 7410 return error::kNoError; 7411 } 7412 GLuint index = c.index; 7413 GLuint divisor = c.divisor; 7414 if (index >= group_->max_vertex_attribs()) { 7415 LOCAL_SET_GL_ERROR( 7416 GL_INVALID_VALUE, 7417 "glVertexAttribDivisorANGLE", "index out of range"); 7418 return error::kNoError; 7419 } 7420 7421 state_.vertex_attrib_manager->SetDivisor( 7422 index, 7423 divisor); 7424 glVertexAttribDivisorANGLE(index, divisor); 7425 return error::kNoError; 7426 } 7427 7428 template <typename pixel_data_type> 7429 static void WriteAlphaData( 7430 void *pixels, uint32 row_count, uint32 channel_count, 7431 uint32 alpha_channel_index, uint32 unpadded_row_size, 7432 uint32 padded_row_size, pixel_data_type alpha_value) { 7433 DCHECK_GT(channel_count, 0U); 7434 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U); 7435 uint32 unpadded_row_size_in_elements = 7436 unpadded_row_size / sizeof(pixel_data_type); 7437 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U); 7438 uint32 padded_row_size_in_elements = 7439 padded_row_size / sizeof(pixel_data_type); 7440 pixel_data_type* dst = 7441 static_cast<pixel_data_type*>(pixels) + alpha_channel_index; 7442 for (uint32 yy = 0; yy < row_count; ++yy) { 7443 pixel_data_type* end = dst + unpadded_row_size_in_elements; 7444 for (pixel_data_type* d = dst; d < end; d += channel_count) { 7445 *d = alpha_value; 7446 } 7447 dst += padded_row_size_in_elements; 7448 } 7449 } 7450 7451 void GLES2DecoderImpl::FinishReadPixels( 7452 const cmds::ReadPixels& c, 7453 GLuint buffer) { 7454 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); 7455 GLsizei width = c.width; 7456 GLsizei height = c.height; 7457 GLenum format = c.format; 7458 GLenum type = c.type; 7459 typedef cmds::ReadPixels::Result Result; 7460 uint32 pixels_size; 7461 Result* result = NULL; 7462 if (c.result_shm_id != 0) { 7463 result = GetSharedMemoryAs<Result*>( 7464 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 7465 if (!result) { 7466 if (buffer != 0) { 7467 glDeleteBuffersARB(1, &buffer); 7468 } 7469 return; 7470 } 7471 } 7472 GLES2Util::ComputeImageDataSizes( 7473 width, height, format, type, state_.pack_alignment, &pixels_size, 7474 NULL, NULL); 7475 void* pixels = GetSharedMemoryAs<void*>( 7476 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 7477 if (!pixels) { 7478 if (buffer != 0) { 7479 glDeleteBuffersARB(1, &buffer); 7480 } 7481 return; 7482 } 7483 7484 if (buffer != 0) { 7485 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 7486 void* data; 7487 if (features().map_buffer_range) { 7488 data = glMapBufferRange( 7489 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); 7490 } else { 7491 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); 7492 } 7493 memcpy(pixels, data, pixels_size); 7494 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't 7495 // have to restore the state. 7496 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); 7497 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7498 glDeleteBuffersARB(1, &buffer); 7499 } 7500 7501 if (result != NULL) { 7502 *result = true; 7503 } 7504 7505 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7506 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7507 if ((channels_exist & 0x0008) == 0 && 7508 workarounds().clear_alpha_in_readpixels) { 7509 // Set the alpha to 255 because some drivers are buggy in this regard. 7510 uint32 temp_size; 7511 7512 uint32 unpadded_row_size; 7513 uint32 padded_row_size; 7514 if (!GLES2Util::ComputeImageDataSizes( 7515 width, 2, format, type, state_.pack_alignment, &temp_size, 7516 &unpadded_row_size, &padded_row_size)) { 7517 return; 7518 } 7519 7520 uint32 channel_count = 0; 7521 uint32 alpha_channel = 0; 7522 switch (format) { 7523 case GL_RGBA: 7524 case GL_BGRA_EXT: 7525 channel_count = 4; 7526 alpha_channel = 3; 7527 break; 7528 case GL_ALPHA: 7529 channel_count = 1; 7530 alpha_channel = 0; 7531 break; 7532 } 7533 7534 if (channel_count > 0) { 7535 switch (type) { 7536 case GL_UNSIGNED_BYTE: 7537 WriteAlphaData<uint8>( 7538 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7539 padded_row_size, 0xFF); 7540 break; 7541 case GL_FLOAT: 7542 WriteAlphaData<float>( 7543 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7544 padded_row_size, 1.0f); 7545 break; 7546 case GL_HALF_FLOAT: 7547 WriteAlphaData<uint16>( 7548 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7549 padded_row_size, 0x3C00); 7550 break; 7551 } 7552 } 7553 } 7554 } 7555 7556 error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, 7557 const void* cmd_data) { 7558 const gles2::cmds::ReadPixels& c = 7559 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data); 7560 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels"); 7561 error::Error fbo_error = WillAccessBoundFramebufferForRead(); 7562 if (fbo_error != error::kNoError) 7563 return fbo_error; 7564 GLint x = c.x; 7565 GLint y = c.y; 7566 GLsizei width = c.width; 7567 GLsizei height = c.height; 7568 GLenum format = c.format; 7569 GLenum type = c.type; 7570 GLboolean async = c.async; 7571 if (width < 0 || height < 0) { 7572 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); 7573 return error::kNoError; 7574 } 7575 typedef cmds::ReadPixels::Result Result; 7576 uint32 pixels_size; 7577 if (!GLES2Util::ComputeImageDataSizes( 7578 width, height, format, type, state_.pack_alignment, &pixels_size, 7579 NULL, NULL)) { 7580 return error::kOutOfBounds; 7581 } 7582 void* pixels = GetSharedMemoryAs<void*>( 7583 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 7584 if (!pixels) { 7585 return error::kOutOfBounds; 7586 } 7587 Result* result = NULL; 7588 if (c.result_shm_id != 0) { 7589 result = GetSharedMemoryAs<Result*>( 7590 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 7591 if (!result) { 7592 return error::kOutOfBounds; 7593 } 7594 } 7595 7596 if (!validators_->read_pixel_format.IsValid(format)) { 7597 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format"); 7598 return error::kNoError; 7599 } 7600 if (!validators_->read_pixel_type.IsValid(type)) { 7601 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type"); 7602 return error::kNoError; 7603 } 7604 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB && 7605 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) { 7606 // format and type are acceptable enums but not guaranteed to be supported 7607 // for this framebuffer. Have to ask gl if they are valid. 7608 GLint preferred_format = 0; 7609 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format); 7610 GLint preferred_type = 0; 7611 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type); 7612 if (format != static_cast<GLenum>(preferred_format) || 7613 type != static_cast<GLenum>(preferred_type)) { 7614 LOCAL_SET_GL_ERROR( 7615 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible " 7616 "with the current read framebuffer"); 7617 return error::kNoError; 7618 } 7619 } 7620 if (width == 0 || height == 0) { 7621 return error::kNoError; 7622 } 7623 7624 // Get the size of the current fbo or backbuffer. 7625 gfx::Size max_size = GetBoundReadFrameBufferSize(); 7626 7627 int32 max_x; 7628 int32 max_y; 7629 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) { 7630 LOCAL_SET_GL_ERROR( 7631 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7632 return error::kNoError; 7633 } 7634 7635 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) { 7636 return error::kNoError; 7637 } 7638 7639 if (!CheckBoundFramebuffersValid("glReadPixels")) { 7640 return error::kNoError; 7641 } 7642 7643 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels"); 7644 7645 ScopedResolvedFrameBufferBinder binder(this, false, true); 7646 7647 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { 7648 // The user requested an out of range area. Get the results 1 line 7649 // at a time. 7650 uint32 temp_size; 7651 uint32 unpadded_row_size; 7652 uint32 padded_row_size; 7653 if (!GLES2Util::ComputeImageDataSizes( 7654 width, 2, format, type, state_.pack_alignment, &temp_size, 7655 &unpadded_row_size, &padded_row_size)) { 7656 LOCAL_SET_GL_ERROR( 7657 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7658 return error::kNoError; 7659 } 7660 7661 GLint dest_x_offset = std::max(-x, 0); 7662 uint32 dest_row_offset; 7663 if (!GLES2Util::ComputeImageDataSizes( 7664 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset, 7665 NULL, NULL)) { 7666 LOCAL_SET_GL_ERROR( 7667 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7668 return error::kNoError; 7669 } 7670 7671 // Copy each row into the larger dest rect. 7672 int8* dst = static_cast<int8*>(pixels); 7673 GLint read_x = std::max(0, x); 7674 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x)); 7675 GLint read_width = read_end_x - read_x; 7676 for (GLint yy = 0; yy < height; ++yy) { 7677 GLint ry = y + yy; 7678 7679 // Clear the row. 7680 memset(dst, 0, unpadded_row_size); 7681 7682 // If the row is in range, copy it. 7683 if (ry >= 0 && ry < max_size.height() && read_width > 0) { 7684 glReadPixels( 7685 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); 7686 } 7687 dst += padded_row_size; 7688 } 7689 } else { 7690 if (async && features().use_async_readpixels) { 7691 GLuint buffer; 7692 glGenBuffersARB(1, &buffer); 7693 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 7694 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); 7695 GLenum error = glGetError(); 7696 if (error == GL_NO_ERROR) { 7697 glReadPixels(x, y, width, height, format, type, 0); 7698 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( 7699 new FenceCallback())); 7700 WaitForReadPixels(base::Bind( 7701 &GLES2DecoderImpl::FinishReadPixels, 7702 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr 7703 <GLES2DecoderImpl>(this), 7704 c, buffer)); 7705 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7706 return error::kNoError; 7707 } else { 7708 // On error, unbind pack buffer and fall through to sync readpixels 7709 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7710 } 7711 } 7712 glReadPixels(x, y, width, height, format, type, pixels); 7713 } 7714 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); 7715 if (error == GL_NO_ERROR) { 7716 if (result != NULL) { 7717 *result = true; 7718 } 7719 FinishReadPixels(c, 0); 7720 } 7721 7722 return error::kNoError; 7723 } 7724 7725 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, 7726 const void* cmd_data) { 7727 const gles2::cmds::PixelStorei& c = 7728 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); 7729 GLenum pname = c.pname; 7730 GLenum param = c.param; 7731 if (!validators_->pixel_store.IsValid(pname)) { 7732 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); 7733 return error::kNoError; 7734 } 7735 switch (pname) { 7736 case GL_PACK_ALIGNMENT: 7737 case GL_UNPACK_ALIGNMENT: 7738 if (!validators_->pixel_store_alignment.IsValid(param)) { 7739 LOCAL_SET_GL_ERROR( 7740 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE"); 7741 return error::kNoError; 7742 } 7743 break; 7744 case GL_UNPACK_FLIP_Y_CHROMIUM: 7745 unpack_flip_y_ = (param != 0); 7746 return error::kNoError; 7747 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 7748 unpack_premultiply_alpha_ = (param != 0); 7749 return error::kNoError; 7750 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 7751 unpack_unpremultiply_alpha_ = (param != 0); 7752 return error::kNoError; 7753 default: 7754 break; 7755 } 7756 glPixelStorei(pname, param); 7757 switch (pname) { 7758 case GL_PACK_ALIGNMENT: 7759 state_.pack_alignment = param; 7760 break; 7761 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 7762 state_.pack_reverse_row_order = (param != 0); 7763 break; 7764 case GL_UNPACK_ALIGNMENT: 7765 state_.unpack_alignment = param; 7766 break; 7767 default: 7768 // Validation should have prevented us from getting here. 7769 NOTREACHED(); 7770 break; 7771 } 7772 return error::kNoError; 7773 } 7774 7775 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( 7776 uint32 immediate_data_size, 7777 const void* cmd_data) { 7778 const gles2::cmds::PostSubBufferCHROMIUM& c = 7779 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data); 7780 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); 7781 { 7782 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame"); 7783 } 7784 if (!supports_post_sub_buffer_) { 7785 LOCAL_SET_GL_ERROR( 7786 GL_INVALID_OPERATION, 7787 "glPostSubBufferCHROMIUM", "command not supported by surface"); 7788 return error::kNoError; 7789 } 7790 bool is_tracing; 7791 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), 7792 &is_tracing); 7793 if (is_tracing) { 7794 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 7795 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); 7796 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( 7797 is_offscreen ? offscreen_size_ : surface_->GetSize()); 7798 } 7799 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) { 7800 return error::kNoError; 7801 } else { 7802 LOG(ERROR) << "Context lost because PostSubBuffer failed."; 7803 return error::kLostContext; 7804 } 7805 } 7806 7807 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM( 7808 uint32 immediate_data_size, 7809 const void* cmd_data) { 7810 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c = 7811 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data); 7812 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id); 7813 if (!ref) { 7814 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, 7815 "glScheduleOverlayPlaneCHROMIUM", 7816 "unknown texture"); 7817 return error::kNoError; 7818 } 7819 gfx::GLImage* image = 7820 ref->texture()->GetLevelImage(ref->texture()->target(), 0); 7821 if (!image) { 7822 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, 7823 "glScheduleOverlayPlaneCHROMIUM", 7824 "unsupported texture format"); 7825 return error::kNoError; 7826 } 7827 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform); 7828 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) { 7829 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, 7830 "glScheduleOverlayPlaneCHROMIUM", 7831 "invalid transform enum"); 7832 return error::kNoError; 7833 } 7834 if (!surface_->ScheduleOverlayPlane( 7835 c.plane_z_order, 7836 transform, 7837 image, 7838 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height), 7839 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) { 7840 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 7841 "glScheduleOverlayPlaneCHROMIUM", 7842 "failed to schedule overlay"); 7843 } 7844 return error::kNoError; 7845 } 7846 7847 error::Error GLES2DecoderImpl::GetAttribLocationHelper( 7848 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7849 const std::string& name_str) { 7850 if (!StringIsValidForGLES(name_str.c_str())) { 7851 LOCAL_SET_GL_ERROR( 7852 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); 7853 return error::kNoError; 7854 } 7855 Program* program = GetProgramInfoNotShader( 7856 client_id, "glGetAttribLocation"); 7857 if (!program) { 7858 return error::kNoError; 7859 } 7860 if (!program->IsValid()) { 7861 LOCAL_SET_GL_ERROR( 7862 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked"); 7863 return error::kNoError; 7864 } 7865 GLint* location = GetSharedMemoryAs<GLint*>( 7866 location_shm_id, location_shm_offset, sizeof(GLint)); 7867 if (!location) { 7868 return error::kOutOfBounds; 7869 } 7870 // Require the client to init this incase the context is lost and we are no 7871 // longer executing commands. 7872 if (*location != -1) { 7873 return error::kGenericError; 7874 } 7875 *location = program->GetAttribLocation(name_str); 7876 return error::kNoError; 7877 } 7878 7879 error::Error GLES2DecoderImpl::HandleGetAttribLocation( 7880 uint32 immediate_data_size, 7881 const void* cmd_data) { 7882 const gles2::cmds::GetAttribLocation& c = 7883 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data); 7884 Bucket* bucket = GetBucket(c.name_bucket_id); 7885 if (!bucket) { 7886 return error::kInvalidArguments; 7887 } 7888 std::string name_str; 7889 if (!bucket->GetAsString(&name_str)) { 7890 return error::kInvalidArguments; 7891 } 7892 return GetAttribLocationHelper( 7893 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7894 } 7895 7896 error::Error GLES2DecoderImpl::GetUniformLocationHelper( 7897 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7898 const std::string& name_str) { 7899 if (!StringIsValidForGLES(name_str.c_str())) { 7900 LOCAL_SET_GL_ERROR( 7901 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); 7902 return error::kNoError; 7903 } 7904 Program* program = GetProgramInfoNotShader( 7905 client_id, "glGetUniformLocation"); 7906 if (!program) { 7907 return error::kNoError; 7908 } 7909 if (!program->IsValid()) { 7910 LOCAL_SET_GL_ERROR( 7911 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked"); 7912 return error::kNoError; 7913 } 7914 GLint* location = GetSharedMemoryAs<GLint*>( 7915 location_shm_id, location_shm_offset, sizeof(GLint)); 7916 if (!location) { 7917 return error::kOutOfBounds; 7918 } 7919 // Require the client to init this incase the context is lost an we are no 7920 // longer executing commands. 7921 if (*location != -1) { 7922 return error::kGenericError; 7923 } 7924 *location = program->GetUniformFakeLocation(name_str); 7925 return error::kNoError; 7926 } 7927 7928 error::Error GLES2DecoderImpl::HandleGetUniformLocation( 7929 uint32 immediate_data_size, 7930 const void* cmd_data) { 7931 const gles2::cmds::GetUniformLocation& c = 7932 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data); 7933 Bucket* bucket = GetBucket(c.name_bucket_id); 7934 if (!bucket) { 7935 return error::kInvalidArguments; 7936 } 7937 std::string name_str; 7938 if (!bucket->GetAsString(&name_str)) { 7939 return error::kInvalidArguments; 7940 } 7941 return GetUniformLocationHelper( 7942 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7943 } 7944 7945 error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, 7946 const void* cmd_data) { 7947 const gles2::cmds::GetString& c = 7948 *static_cast<const gles2::cmds::GetString*>(cmd_data); 7949 GLenum name = static_cast<GLenum>(c.name); 7950 if (!validators_->string_type.IsValid(name)) { 7951 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name"); 7952 return error::kNoError; 7953 } 7954 const char* str = reinterpret_cast<const char*>(glGetString(name)); 7955 std::string extensions; 7956 switch (name) { 7957 case GL_VERSION: 7958 str = "OpenGL ES 2.0 Chromium"; 7959 break; 7960 case GL_SHADING_LANGUAGE_VERSION: 7961 str = "OpenGL ES GLSL ES 1.0 Chromium"; 7962 break; 7963 case GL_RENDERER: 7964 case GL_VENDOR: 7965 // Return the unmasked VENDOR/RENDERER string for WebGL contexts. 7966 // They are used by WEBGL_debug_renderer_info. 7967 if (!force_webgl_glsl_validation_) 7968 str = "Chromium"; 7969 break; 7970 case GL_EXTENSIONS: 7971 { 7972 // For WebGL contexts, strip out the OES derivatives and 7973 // EXT frag depth extensions if they have not been enabled. 7974 if (force_webgl_glsl_validation_) { 7975 extensions = feature_info_->extensions(); 7976 if (!derivatives_explicitly_enabled_) { 7977 size_t offset = extensions.find(kOESDerivativeExtension); 7978 if (std::string::npos != offset) { 7979 extensions.replace(offset, arraysize(kOESDerivativeExtension), 7980 std::string()); 7981 } 7982 } 7983 if (!frag_depth_explicitly_enabled_) { 7984 size_t offset = extensions.find(kEXTFragDepthExtension); 7985 if (std::string::npos != offset) { 7986 extensions.replace(offset, arraysize(kEXTFragDepthExtension), 7987 std::string()); 7988 } 7989 } 7990 if (!draw_buffers_explicitly_enabled_) { 7991 size_t offset = extensions.find(kEXTDrawBuffersExtension); 7992 if (std::string::npos != offset) { 7993 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension), 7994 std::string()); 7995 } 7996 } 7997 if (!shader_texture_lod_explicitly_enabled_) { 7998 size_t offset = extensions.find(kEXTShaderTextureLodExtension); 7999 if (std::string::npos != offset) { 8000 extensions.replace(offset, 8001 arraysize(kEXTShaderTextureLodExtension), 8002 std::string()); 8003 } 8004 } 8005 } else { 8006 extensions = feature_info_->extensions().c_str(); 8007 } 8008 if (supports_post_sub_buffer_) 8009 extensions += " GL_CHROMIUM_post_sub_buffer"; 8010 str = extensions.c_str(); 8011 } 8012 break; 8013 default: 8014 break; 8015 } 8016 Bucket* bucket = CreateBucket(c.bucket_id); 8017 bucket->SetFromString(str); 8018 return error::kNoError; 8019 } 8020 8021 error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size, 8022 const void* cmd_data) { 8023 const gles2::cmds::BufferData& c = 8024 *static_cast<const gles2::cmds::BufferData*>(cmd_data); 8025 GLenum target = static_cast<GLenum>(c.target); 8026 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 8027 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 8028 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 8029 GLenum usage = static_cast<GLenum>(c.usage); 8030 const void* data = NULL; 8031 if (data_shm_id != 0 || data_shm_offset != 0) { 8032 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); 8033 if (!data) { 8034 return error::kOutOfBounds; 8035 } 8036 } 8037 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage); 8038 return error::kNoError; 8039 } 8040 8041 void GLES2DecoderImpl::DoBufferSubData( 8042 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { 8043 // Just delegate it. Some validation is actually done before this. 8044 buffer_manager()->ValidateAndDoBufferSubData( 8045 &state_, target, offset, size, data); 8046 } 8047 8048 bool GLES2DecoderImpl::ClearLevel( 8049 unsigned service_id, 8050 unsigned bind_target, 8051 unsigned target, 8052 int level, 8053 unsigned internal_format, 8054 unsigned format, 8055 unsigned type, 8056 int width, 8057 int height, 8058 bool is_texture_immutable) { 8059 uint32 channels = GLES2Util::GetChannelsForFormat(format); 8060 if (feature_info_->feature_flags().angle_depth_texture && 8061 (channels & GLES2Util::kDepth) != 0) { 8062 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D 8063 // on depth formats. 8064 GLuint fb = 0; 8065 glGenFramebuffersEXT(1, &fb); 8066 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); 8067 8068 bool have_stencil = (channels & GLES2Util::kStencil) != 0; 8069 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : 8070 GL_DEPTH_ATTACHMENT; 8071 8072 glFramebufferTexture2DEXT( 8073 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); 8074 // ANGLE promises a depth only attachment ok. 8075 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != 8076 GL_FRAMEBUFFER_COMPLETE) { 8077 return false; 8078 } 8079 glClearStencil(0); 8080 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); 8081 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); 8082 glClearDepth(1.0f); 8083 state_.SetDeviceDepthMask(GL_TRUE); 8084 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 8085 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0)); 8086 8087 RestoreClearState(); 8088 8089 glDeleteFramebuffersEXT(1, &fb); 8090 Framebuffer* framebuffer = 8091 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 8092 GLuint fb_service_id = 8093 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); 8094 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id); 8095 return true; 8096 } 8097 8098 static const uint32 kMaxZeroSize = 1024 * 1024 * 4; 8099 8100 uint32 size; 8101 uint32 padded_row_size; 8102 if (!GLES2Util::ComputeImageDataSizes( 8103 width, height, format, type, state_.unpack_alignment, &size, 8104 NULL, &padded_row_size)) { 8105 return false; 8106 } 8107 8108 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size); 8109 8110 int tile_height; 8111 8112 if (size > kMaxZeroSize) { 8113 if (kMaxZeroSize < padded_row_size) { 8114 // That'd be an awfully large texture. 8115 return false; 8116 } 8117 // We should never have a large total size with a zero row size. 8118 DCHECK_GT(padded_row_size, 0U); 8119 tile_height = kMaxZeroSize / padded_row_size; 8120 if (!GLES2Util::ComputeImageDataSizes( 8121 width, tile_height, format, type, state_.unpack_alignment, &size, 8122 NULL, NULL)) { 8123 return false; 8124 } 8125 } else { 8126 tile_height = height; 8127 } 8128 8129 // Assumes the size has already been checked. 8130 scoped_ptr<char[]> zero(new char[size]); 8131 memset(zero.get(), 0, size); 8132 glBindTexture(bind_target, service_id); 8133 8134 GLint y = 0; 8135 while (y < height) { 8136 GLint h = y + tile_height > height ? height - y : tile_height; 8137 if (is_texture_immutable || h != height) { 8138 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); 8139 } else { 8140 glTexImage2D( 8141 target, level, internal_format, width, h, 0, format, type, 8142 zero.get()); 8143 } 8144 y += tile_height; 8145 } 8146 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 8147 &state_, bind_target); 8148 glBindTexture(bind_target, texture ? texture->service_id() : 0); 8149 return true; 8150 } 8151 8152 namespace { 8153 8154 const int kS3TCBlockWidth = 4; 8155 const int kS3TCBlockHeight = 4; 8156 const int kS3TCDXT1BlockSize = 8; 8157 const int kS3TCDXT3AndDXT5BlockSize = 16; 8158 8159 bool IsValidDXTSize(GLint level, GLsizei size) { 8160 return (size == 1) || 8161 (size == 2) || !(size % kS3TCBlockWidth); 8162 } 8163 8164 bool IsValidPVRTCSize(GLint level, GLsizei size) { 8165 return GLES2Util::IsPOT(size); 8166 } 8167 8168 } // anonymous namespace. 8169 8170 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( 8171 const char* function_name, 8172 GLsizei width, GLsizei height, GLenum format, size_t size) { 8173 unsigned int bytes_required = 0; 8174 8175 switch (format) { 8176 case GL_ATC_RGB_AMD: 8177 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 8178 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 8179 case GL_ETC1_RGB8_OES: { 8180 int num_blocks_across = 8181 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 8182 int num_blocks_down = 8183 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 8184 int num_blocks = num_blocks_across * num_blocks_down; 8185 bytes_required = num_blocks * kS3TCDXT1BlockSize; 8186 break; 8187 } 8188 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: 8189 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: 8190 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 8191 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 8192 int num_blocks_across = 8193 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 8194 int num_blocks_down = 8195 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 8196 int num_blocks = num_blocks_across * num_blocks_down; 8197 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; 8198 break; 8199 } 8200 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 8201 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: { 8202 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8; 8203 break; 8204 } 8205 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 8206 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { 8207 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8; 8208 break; 8209 } 8210 default: 8211 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); 8212 return false; 8213 } 8214 8215 if (size != bytes_required) { 8216 LOCAL_SET_GL_ERROR( 8217 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); 8218 return false; 8219 } 8220 8221 return true; 8222 } 8223 8224 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( 8225 const char* function_name, 8226 GLint level, GLsizei width, GLsizei height, GLenum format) { 8227 switch (format) { 8228 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 8229 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 8230 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 8231 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 8232 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { 8233 LOCAL_SET_GL_ERROR( 8234 GL_INVALID_OPERATION, function_name, 8235 "width or height invalid for level"); 8236 return false; 8237 } 8238 return true; 8239 } 8240 case GL_ATC_RGB_AMD: 8241 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: 8242 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: 8243 case GL_ETC1_RGB8_OES: { 8244 if (width <= 0 || height <= 0) { 8245 LOCAL_SET_GL_ERROR( 8246 GL_INVALID_OPERATION, function_name, 8247 "width or height invalid for level"); 8248 return false; 8249 } 8250 return true; 8251 } 8252 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 8253 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 8254 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 8255 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { 8256 if (!IsValidPVRTCSize(level, width) || 8257 !IsValidPVRTCSize(level, height)) { 8258 LOCAL_SET_GL_ERROR( 8259 GL_INVALID_OPERATION, function_name, 8260 "width or height invalid for level"); 8261 return false; 8262 } 8263 return true; 8264 } 8265 default: 8266 return false; 8267 } 8268 } 8269 8270 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( 8271 const char* function_name, 8272 GLenum target, GLint level, GLint xoffset, GLint yoffset, 8273 GLsizei width, GLsizei height, GLenum format, 8274 Texture* texture) { 8275 if (xoffset < 0 || yoffset < 0) { 8276 LOCAL_SET_GL_ERROR( 8277 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0"); 8278 return false; 8279 } 8280 8281 switch (format) { 8282 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 8283 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 8284 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 8285 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 8286 const int kBlockWidth = 4; 8287 const int kBlockHeight = 4; 8288 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { 8289 LOCAL_SET_GL_ERROR( 8290 GL_INVALID_OPERATION, function_name, 8291 "xoffset or yoffset not multiple of 4"); 8292 return false; 8293 } 8294 GLsizei tex_width = 0; 8295 GLsizei tex_height = 0; 8296 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || 8297 width - xoffset > tex_width || 8298 height - yoffset > tex_height) { 8299 LOCAL_SET_GL_ERROR( 8300 GL_INVALID_OPERATION, function_name, "dimensions out of range"); 8301 return false; 8302 } 8303 return ValidateCompressedTexDimensions( 8304 function_name, level, width, height, format); 8305 } 8306 case GL_ATC_RGB_AMD: 8307 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: 8308 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: { 8309 LOCAL_SET_GL_ERROR( 8310 GL_INVALID_OPERATION, function_name, 8311 "not supported for ATC textures"); 8312 return false; 8313 } 8314 case GL_ETC1_RGB8_OES: { 8315 LOCAL_SET_GL_ERROR( 8316 GL_INVALID_OPERATION, function_name, 8317 "not supported for ECT1_RGB8_OES textures"); 8318 return false; 8319 } 8320 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 8321 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 8322 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 8323 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { 8324 if ((xoffset != 0) || (yoffset != 0)) { 8325 LOCAL_SET_GL_ERROR( 8326 GL_INVALID_OPERATION, function_name, 8327 "xoffset and yoffset must be zero"); 8328 return false; 8329 } 8330 GLsizei tex_width = 0; 8331 GLsizei tex_height = 0; 8332 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || 8333 width != tex_width || 8334 height != tex_height) { 8335 LOCAL_SET_GL_ERROR( 8336 GL_INVALID_OPERATION, function_name, 8337 "dimensions must match existing texture level dimensions"); 8338 return false; 8339 } 8340 return ValidateCompressedTexDimensions( 8341 function_name, level, width, height, format); 8342 } 8343 default: 8344 return false; 8345 } 8346 } 8347 8348 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( 8349 GLenum target, 8350 GLint level, 8351 GLenum internal_format, 8352 GLsizei width, 8353 GLsizei height, 8354 GLint border, 8355 GLsizei image_size, 8356 const void* data) { 8357 // TODO(gman): Validate image_size is correct for width, height and format. 8358 if (!validators_->texture_target.IsValid(target)) { 8359 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8360 "glCompressedTexImage2D", target, "target"); 8361 return error::kNoError; 8362 } 8363 if (!validators_->compressed_texture_format.IsValid( 8364 internal_format)) { 8365 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8366 "glCompressedTexImage2D", internal_format, "internal_format"); 8367 return error::kNoError; 8368 } 8369 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 8370 border != 0) { 8371 LOCAL_SET_GL_ERROR( 8372 GL_INVALID_VALUE, 8373 "glCompressedTexImage2D", "dimensions out of range"); 8374 return error::kNoError; 8375 } 8376 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8377 &state_, target); 8378 if (!texture_ref) { 8379 LOCAL_SET_GL_ERROR( 8380 GL_INVALID_VALUE, 8381 "glCompressedTexImage2D", "unknown texture target"); 8382 return error::kNoError; 8383 } 8384 Texture* texture = texture_ref->texture(); 8385 if (texture->IsImmutable()) { 8386 LOCAL_SET_GL_ERROR( 8387 GL_INVALID_OPERATION, 8388 "glCompressedTexImage2D", "texture is immutable"); 8389 return error::kNoError; 8390 } 8391 8392 if (!ValidateCompressedTexDimensions( 8393 "glCompressedTexImage2D", level, width, height, internal_format) || 8394 !ValidateCompressedTexFuncData( 8395 "glCompressedTexImage2D", width, height, internal_format, image_size)) { 8396 return error::kNoError; 8397 } 8398 8399 if (!EnsureGPUMemoryAvailable(image_size)) { 8400 LOCAL_SET_GL_ERROR( 8401 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); 8402 return error::kNoError; 8403 } 8404 8405 if (texture->IsAttachedToFramebuffer()) { 8406 framebuffer_state_.clear_state_dirty = true; 8407 } 8408 8409 scoped_ptr<int8[]> zero; 8410 if (!data) { 8411 zero.reset(new int8[image_size]); 8412 memset(zero.get(), 0, image_size); 8413 data = zero.get(); 8414 } 8415 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); 8416 glCompressedTexImage2D( 8417 target, level, internal_format, width, height, border, image_size, data); 8418 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); 8419 if (error == GL_NO_ERROR) { 8420 texture_manager()->SetLevelInfo( 8421 texture_ref, target, level, internal_format, 8422 width, height, 1, border, 0, 0, true); 8423 } 8424 8425 // This may be a slow command. Exit command processing to allow for 8426 // context preemption and GPU watchdog checks. 8427 ExitCommandProcessingEarly(); 8428 return error::kNoError; 8429 } 8430 8431 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( 8432 uint32 immediate_data_size, 8433 const void* cmd_data) { 8434 const gles2::cmds::CompressedTexImage2D& c = 8435 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data); 8436 GLenum target = static_cast<GLenum>(c.target); 8437 GLint level = static_cast<GLint>(c.level); 8438 GLenum internal_format = static_cast<GLenum>(c.internalformat); 8439 GLsizei width = static_cast<GLsizei>(c.width); 8440 GLsizei height = static_cast<GLsizei>(c.height); 8441 GLint border = static_cast<GLint>(c.border); 8442 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 8443 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 8444 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 8445 const void* data = NULL; 8446 if (data_shm_id != 0 || data_shm_offset != 0) { 8447 data = GetSharedMemoryAs<const void*>( 8448 data_shm_id, data_shm_offset, image_size); 8449 if (!data) { 8450 return error::kOutOfBounds; 8451 } 8452 } 8453 return DoCompressedTexImage2D( 8454 target, level, internal_format, width, height, border, image_size, data); 8455 } 8456 8457 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket( 8458 uint32 immediate_data_size, 8459 const void* cmd_data) { 8460 const gles2::cmds::CompressedTexImage2DBucket& c = 8461 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data); 8462 GLenum target = static_cast<GLenum>(c.target); 8463 GLint level = static_cast<GLint>(c.level); 8464 GLenum internal_format = static_cast<GLenum>(c.internalformat); 8465 GLsizei width = static_cast<GLsizei>(c.width); 8466 GLsizei height = static_cast<GLsizei>(c.height); 8467 GLint border = static_cast<GLint>(c.border); 8468 Bucket* bucket = GetBucket(c.bucket_id); 8469 if (!bucket) { 8470 return error::kInvalidArguments; 8471 } 8472 uint32 data_size = bucket->size(); 8473 GLsizei imageSize = data_size; 8474 const void* data = bucket->GetData(0, data_size); 8475 if (!data) { 8476 return error::kInvalidArguments; 8477 } 8478 return DoCompressedTexImage2D( 8479 target, level, internal_format, width, height, border, 8480 imageSize, data); 8481 } 8482 8483 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( 8484 uint32 immediate_data_size, 8485 const void* cmd_data) { 8486 const gles2::cmds::CompressedTexSubImage2DBucket& c = 8487 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data); 8488 GLenum target = static_cast<GLenum>(c.target); 8489 GLint level = static_cast<GLint>(c.level); 8490 GLint xoffset = static_cast<GLint>(c.xoffset); 8491 GLint yoffset = static_cast<GLint>(c.yoffset); 8492 GLsizei width = static_cast<GLsizei>(c.width); 8493 GLsizei height = static_cast<GLsizei>(c.height); 8494 GLenum format = static_cast<GLenum>(c.format); 8495 Bucket* bucket = GetBucket(c.bucket_id); 8496 if (!bucket) { 8497 return error::kInvalidArguments; 8498 } 8499 uint32 data_size = bucket->size(); 8500 GLsizei imageSize = data_size; 8501 const void* data = bucket->GetData(0, data_size); 8502 if (!data) { 8503 return error::kInvalidArguments; 8504 } 8505 if (!validators_->texture_target.IsValid(target)) { 8506 LOCAL_SET_GL_ERROR( 8507 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target"); 8508 return error::kNoError; 8509 } 8510 if (!validators_->compressed_texture_format.IsValid(format)) { 8511 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8512 "glCompressedTexSubImage2D", format, "format"); 8513 return error::kNoError; 8514 } 8515 if (width < 0) { 8516 LOCAL_SET_GL_ERROR( 8517 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0"); 8518 return error::kNoError; 8519 } 8520 if (height < 0) { 8521 LOCAL_SET_GL_ERROR( 8522 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0"); 8523 return error::kNoError; 8524 } 8525 if (imageSize < 0) { 8526 LOCAL_SET_GL_ERROR( 8527 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0"); 8528 return error::kNoError; 8529 } 8530 DoCompressedTexSubImage2D( 8531 target, level, xoffset, yoffset, width, height, format, imageSize, data); 8532 return error::kNoError; 8533 } 8534 8535 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size, 8536 const void* cmd_data) { 8537 const gles2::cmds::TexImage2D& c = 8538 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); 8539 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", 8540 "width", c.width, "height", c.height); 8541 // Set as failed for now, but if it successed, this will be set to not failed. 8542 texture_state_.tex_image_2d_failed = true; 8543 GLenum target = static_cast<GLenum>(c.target); 8544 GLint level = static_cast<GLint>(c.level); 8545 // TODO(kloveless): Change TexImage2D command to use unsigned integer 8546 // for internalformat. 8547 GLenum internal_format = static_cast<GLenum>(c.internalformat); 8548 GLsizei width = static_cast<GLsizei>(c.width); 8549 GLsizei height = static_cast<GLsizei>(c.height); 8550 GLint border = static_cast<GLint>(c.border); 8551 GLenum format = static_cast<GLenum>(c.format); 8552 GLenum type = static_cast<GLenum>(c.type); 8553 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 8554 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 8555 uint32 pixels_size; 8556 if (!GLES2Util::ComputeImageDataSizes( 8557 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 8558 NULL)) { 8559 return error::kOutOfBounds; 8560 } 8561 const void* pixels = NULL; 8562 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 8563 pixels = GetSharedMemoryAs<const void*>( 8564 pixels_shm_id, pixels_shm_offset, pixels_size); 8565 if (!pixels) { 8566 return error::kOutOfBounds; 8567 } 8568 } 8569 8570 TextureManager::DoTextImage2DArguments args = { 8571 target, level, internal_format, width, height, border, format, type, 8572 pixels, pixels_size}; 8573 texture_manager()->ValidateAndDoTexImage2D( 8574 &texture_state_, &state_, &framebuffer_state_, args); 8575 8576 // This may be a slow command. Exit command processing to allow for 8577 // context preemption and GPU watchdog checks. 8578 ExitCommandProcessingEarly(); 8579 return error::kNoError; 8580 } 8581 8582 void GLES2DecoderImpl::DoCompressedTexSubImage2D( 8583 GLenum target, 8584 GLint level, 8585 GLint xoffset, 8586 GLint yoffset, 8587 GLsizei width, 8588 GLsizei height, 8589 GLenum format, 8590 GLsizei image_size, 8591 const void * data) { 8592 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8593 &state_, target); 8594 if (!texture_ref) { 8595 LOCAL_SET_GL_ERROR( 8596 GL_INVALID_OPERATION, 8597 "glCompressedTexSubImage2D", "unknown texture for target"); 8598 return; 8599 } 8600 Texture* texture = texture_ref->texture(); 8601 GLenum type = 0; 8602 GLenum internal_format = 0; 8603 if (!texture->GetLevelType(target, level, &type, &internal_format)) { 8604 LOCAL_SET_GL_ERROR( 8605 GL_INVALID_OPERATION, 8606 "glCompressedTexSubImage2D", "level does not exist."); 8607 return; 8608 } 8609 if (internal_format != format) { 8610 LOCAL_SET_GL_ERROR( 8611 GL_INVALID_OPERATION, 8612 "glCompressedTexSubImage2D", "format does not match internal format."); 8613 return; 8614 } 8615 if (!texture->ValidForTexture( 8616 target, level, xoffset, yoffset, width, height, type)) { 8617 LOCAL_SET_GL_ERROR( 8618 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); 8619 return; 8620 } 8621 8622 if (!ValidateCompressedTexFuncData( 8623 "glCompressedTexSubImage2D", width, height, format, image_size) || 8624 !ValidateCompressedTexSubDimensions( 8625 "glCompressedTexSubImage2D", 8626 target, level, xoffset, yoffset, width, height, format, texture)) { 8627 return; 8628 } 8629 8630 8631 // Note: There is no need to deal with texture cleared tracking here 8632 // because the validation above means you can only get here if the level 8633 // is already a matching compressed format and in that case 8634 // CompressedTexImage2D already cleared the texture. 8635 glCompressedTexSubImage2D( 8636 target, level, xoffset, yoffset, width, height, format, image_size, data); 8637 8638 // This may be a slow command. Exit command processing to allow for 8639 // context preemption and GPU watchdog checks. 8640 ExitCommandProcessingEarly(); 8641 } 8642 8643 static void Clip( 8644 GLint start, GLint range, GLint sourceRange, 8645 GLint* out_start, GLint* out_range) { 8646 DCHECK(out_start); 8647 DCHECK(out_range); 8648 if (start < 0) { 8649 range += start; 8650 start = 0; 8651 } 8652 GLint end = start + range; 8653 if (end > sourceRange) { 8654 range -= end - sourceRange; 8655 } 8656 *out_start = start; 8657 *out_range = range; 8658 } 8659 8660 void GLES2DecoderImpl::DoCopyTexImage2D( 8661 GLenum target, 8662 GLint level, 8663 GLenum internal_format, 8664 GLint x, 8665 GLint y, 8666 GLsizei width, 8667 GLsizei height, 8668 GLint border) { 8669 DCHECK(!ShouldDeferReads()); 8670 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8671 &state_, target); 8672 if (!texture_ref) { 8673 LOCAL_SET_GL_ERROR( 8674 GL_INVALID_OPERATION, 8675 "glCopyTexImage2D", "unknown texture for target"); 8676 return; 8677 } 8678 Texture* texture = texture_ref->texture(); 8679 if (texture->IsImmutable()) { 8680 LOCAL_SET_GL_ERROR( 8681 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable"); 8682 return; 8683 } 8684 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 8685 border != 0) { 8686 LOCAL_SET_GL_ERROR( 8687 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); 8688 return; 8689 } 8690 if (!texture_manager()->ValidateFormatAndTypeCombination( 8691 state_.GetErrorState(), "glCopyTexImage2D", internal_format, 8692 GL_UNSIGNED_BYTE)) { 8693 return; 8694 } 8695 8696 // Check we have compatible formats. 8697 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 8698 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 8699 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); 8700 8701 if ((channels_needed & channels_exist) != channels_needed) { 8702 LOCAL_SET_GL_ERROR( 8703 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); 8704 return; 8705 } 8706 8707 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8708 LOCAL_SET_GL_ERROR( 8709 GL_INVALID_OPERATION, 8710 "glCopyTexImage2D", "can not be used with depth or stencil textures"); 8711 return; 8712 } 8713 8714 uint32 estimated_size = 0; 8715 if (!GLES2Util::ComputeImageDataSizes( 8716 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment, 8717 &estimated_size, NULL, NULL)) { 8718 LOCAL_SET_GL_ERROR( 8719 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large"); 8720 return; 8721 } 8722 8723 if (!EnsureGPUMemoryAvailable(estimated_size)) { 8724 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory"); 8725 return; 8726 } 8727 8728 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) { 8729 return; 8730 } 8731 8732 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { 8733 return; 8734 } 8735 8736 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D"); 8737 ScopedResolvedFrameBufferBinder binder(this, false, true); 8738 gfx::Size size = GetBoundReadFrameBufferSize(); 8739 8740 if (texture->IsAttachedToFramebuffer()) { 8741 framebuffer_state_.clear_state_dirty = true; 8742 } 8743 8744 // Clip to size to source dimensions 8745 GLint copyX = 0; 8746 GLint copyY = 0; 8747 GLint copyWidth = 0; 8748 GLint copyHeight = 0; 8749 Clip(x, width, size.width(), ©X, ©Width); 8750 Clip(y, height, size.height(), ©Y, ©Height); 8751 8752 if (copyX != x || 8753 copyY != y || 8754 copyWidth != width || 8755 copyHeight != height) { 8756 // some part was clipped so clear the texture. 8757 if (!ClearLevel( 8758 texture->service_id(), texture->target(), 8759 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE, 8760 width, height, texture->IsImmutable())) { 8761 LOCAL_SET_GL_ERROR( 8762 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); 8763 return; 8764 } 8765 if (copyHeight > 0 && copyWidth > 0) { 8766 GLint dx = copyX - x; 8767 GLint dy = copyY - y; 8768 GLint destX = dx; 8769 GLint destY = dy; 8770 ScopedModifyPixels modify(texture_ref); 8771 glCopyTexSubImage2D(target, level, 8772 destX, destY, copyX, copyY, 8773 copyWidth, copyHeight); 8774 } 8775 } else { 8776 ScopedModifyPixels modify(texture_ref); 8777 glCopyTexImage2D(target, level, internal_format, 8778 copyX, copyY, copyWidth, copyHeight, border); 8779 } 8780 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); 8781 if (error == GL_NO_ERROR) { 8782 texture_manager()->SetLevelInfo( 8783 texture_ref, target, level, internal_format, width, height, 1, 8784 border, internal_format, GL_UNSIGNED_BYTE, true); 8785 } 8786 8787 // This may be a slow command. Exit command processing to allow for 8788 // context preemption and GPU watchdog checks. 8789 ExitCommandProcessingEarly(); 8790 } 8791 8792 void GLES2DecoderImpl::DoCopyTexSubImage2D( 8793 GLenum target, 8794 GLint level, 8795 GLint xoffset, 8796 GLint yoffset, 8797 GLint x, 8798 GLint y, 8799 GLsizei width, 8800 GLsizei height) { 8801 DCHECK(!ShouldDeferReads()); 8802 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8803 &state_, target); 8804 if (!texture_ref) { 8805 LOCAL_SET_GL_ERROR( 8806 GL_INVALID_OPERATION, 8807 "glCopyTexSubImage2D", "unknown texture for target"); 8808 return; 8809 } 8810 Texture* texture = texture_ref->texture(); 8811 GLenum type = 0; 8812 GLenum format = 0; 8813 if (!texture->GetLevelType(target, level, &type, &format) || 8814 !texture->ValidForTexture( 8815 target, level, xoffset, yoffset, width, height, type)) { 8816 LOCAL_SET_GL_ERROR( 8817 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions."); 8818 return; 8819 } 8820 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 8821 LOCAL_SET_GL_ERROR( 8822 GL_INVALID_OPERATION, 8823 "glCopyTexSubImage2D", "async upload pending for texture"); 8824 return; 8825 } 8826 8827 // Check we have compatible formats. 8828 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 8829 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 8830 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); 8831 8832 if (!channels_needed || 8833 (channels_needed & channels_exist) != channels_needed) { 8834 LOCAL_SET_GL_ERROR( 8835 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); 8836 return; 8837 } 8838 8839 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8840 LOCAL_SET_GL_ERROR( 8841 GL_INVALID_OPERATION, 8842 "glCopySubImage2D", "can not be used with depth or stencil textures"); 8843 return; 8844 } 8845 8846 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) { 8847 return; 8848 } 8849 8850 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { 8851 return; 8852 } 8853 8854 ScopedResolvedFrameBufferBinder binder(this, false, true); 8855 gfx::Size size = GetBoundReadFrameBufferSize(); 8856 GLint copyX = 0; 8857 GLint copyY = 0; 8858 GLint copyWidth = 0; 8859 GLint copyHeight = 0; 8860 Clip(x, width, size.width(), ©X, ©Width); 8861 Clip(y, height, size.height(), ©Y, ©Height); 8862 8863 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) { 8864 LOCAL_SET_GL_ERROR( 8865 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); 8866 return; 8867 } 8868 8869 if (copyX != x || 8870 copyY != y || 8871 copyWidth != width || 8872 copyHeight != height) { 8873 // some part was clipped so clear the sub rect. 8874 uint32 pixels_size = 0; 8875 if (!GLES2Util::ComputeImageDataSizes( 8876 width, height, format, type, state_.unpack_alignment, &pixels_size, 8877 NULL, NULL)) { 8878 LOCAL_SET_GL_ERROR( 8879 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); 8880 return; 8881 } 8882 scoped_ptr<char[]> zero(new char[pixels_size]); 8883 memset(zero.get(), 0, pixels_size); 8884 ScopedModifyPixels modify(texture_ref); 8885 glTexSubImage2D( 8886 target, level, xoffset, yoffset, width, height, 8887 format, type, zero.get()); 8888 } 8889 8890 if (copyHeight > 0 && copyWidth > 0) { 8891 GLint dx = copyX - x; 8892 GLint dy = copyY - y; 8893 GLint destX = xoffset + dx; 8894 GLint destY = yoffset + dy; 8895 ScopedModifyPixels modify(texture_ref); 8896 glCopyTexSubImage2D(target, level, 8897 destX, destY, copyX, copyY, 8898 copyWidth, copyHeight); 8899 } 8900 8901 // This may be a slow command. Exit command processing to allow for 8902 // context preemption and GPU watchdog checks. 8903 ExitCommandProcessingEarly(); 8904 } 8905 8906 bool GLES2DecoderImpl::ValidateTexSubImage2D( 8907 error::Error* error, 8908 const char* function_name, 8909 GLenum target, 8910 GLint level, 8911 GLint xoffset, 8912 GLint yoffset, 8913 GLsizei width, 8914 GLsizei height, 8915 GLenum format, 8916 GLenum type, 8917 const void * data) { 8918 (*error) = error::kNoError; 8919 if (!validators_->texture_target.IsValid(target)) { 8920 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target"); 8921 return false; 8922 } 8923 if (width < 0) { 8924 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0"); 8925 return false; 8926 } 8927 if (height < 0) { 8928 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0"); 8929 return false; 8930 } 8931 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8932 &state_, target); 8933 if (!texture_ref) { 8934 LOCAL_SET_GL_ERROR( 8935 GL_INVALID_OPERATION, 8936 function_name, "unknown texture for target"); 8937 return false; 8938 } 8939 Texture* texture = texture_ref->texture(); 8940 GLenum current_type = 0; 8941 GLenum internal_format = 0; 8942 if (!texture->GetLevelType(target, level, ¤t_type, &internal_format)) { 8943 LOCAL_SET_GL_ERROR( 8944 GL_INVALID_OPERATION, function_name, "level does not exist."); 8945 return false; 8946 } 8947 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(), 8948 function_name, format, type, internal_format, level)) { 8949 return false; 8950 } 8951 if (type != current_type) { 8952 LOCAL_SET_GL_ERROR( 8953 GL_INVALID_OPERATION, 8954 function_name, "type does not match type of texture."); 8955 return false; 8956 } 8957 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 8958 LOCAL_SET_GL_ERROR( 8959 GL_INVALID_OPERATION, 8960 function_name, "async upload pending for texture"); 8961 return false; 8962 } 8963 if (!texture->ValidForTexture( 8964 target, level, xoffset, yoffset, width, height, type)) { 8965 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions."); 8966 return false; 8967 } 8968 if ((GLES2Util::GetChannelsForFormat(format) & 8969 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8970 LOCAL_SET_GL_ERROR( 8971 GL_INVALID_OPERATION, 8972 function_name, "can not supply data for depth or stencil textures"); 8973 return false; 8974 } 8975 if (data == NULL) { 8976 (*error) = error::kOutOfBounds; 8977 return false; 8978 } 8979 return true; 8980 } 8981 8982 error::Error GLES2DecoderImpl::DoTexSubImage2D( 8983 GLenum target, 8984 GLint level, 8985 GLint xoffset, 8986 GLint yoffset, 8987 GLsizei width, 8988 GLsizei height, 8989 GLenum format, 8990 GLenum type, 8991 const void * data) { 8992 error::Error error = error::kNoError; 8993 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level, 8994 xoffset, yoffset, width, height, format, type, data)) { 8995 return error; 8996 } 8997 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 8998 &state_, target); 8999 Texture* texture = texture_ref->texture(); 9000 GLsizei tex_width = 0; 9001 GLsizei tex_height = 0; 9002 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height); 9003 DCHECK(ok); 9004 if (xoffset != 0 || yoffset != 0 || 9005 width != tex_width || height != tex_height) { 9006 if (!texture_manager()->ClearTextureLevel(this, texture_ref, 9007 target, level)) { 9008 LOCAL_SET_GL_ERROR( 9009 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); 9010 return error::kNoError; 9011 } 9012 ScopedTextureUploadTimer timer(&texture_state_); 9013 glTexSubImage2D( 9014 target, level, xoffset, yoffset, width, height, format, type, data); 9015 return error::kNoError; 9016 } 9017 9018 if (!texture_state_.texsubimage2d_faster_than_teximage2d && 9019 !texture->IsImmutable()) { 9020 ScopedTextureUploadTimer timer(&texture_state_); 9021 GLenum internal_format; 9022 GLenum tex_type; 9023 texture->GetLevelType(target, level, &tex_type, &internal_format); 9024 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need 9025 // to look it up. 9026 glTexImage2D( 9027 target, level, internal_format, width, height, 0, format, type, data); 9028 } else { 9029 ScopedTextureUploadTimer timer(&texture_state_); 9030 glTexSubImage2D( 9031 target, level, xoffset, yoffset, width, height, format, type, data); 9032 } 9033 texture_manager()->SetLevelCleared(texture_ref, target, level, true); 9034 9035 // This may be a slow command. Exit command processing to allow for 9036 // context preemption and GPU watchdog checks. 9037 ExitCommandProcessingEarly(); 9038 return error::kNoError; 9039 } 9040 9041 error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size, 9042 const void* cmd_data) { 9043 const gles2::cmds::TexSubImage2D& c = 9044 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data); 9045 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D", 9046 "width", c.width, "height", c.height); 9047 GLboolean internal = static_cast<GLboolean>(c.internal); 9048 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed) 9049 return error::kNoError; 9050 9051 GLenum target = static_cast<GLenum>(c.target); 9052 GLint level = static_cast<GLint>(c.level); 9053 GLint xoffset = static_cast<GLint>(c.xoffset); 9054 GLint yoffset = static_cast<GLint>(c.yoffset); 9055 GLsizei width = static_cast<GLsizei>(c.width); 9056 GLsizei height = static_cast<GLsizei>(c.height); 9057 GLenum format = static_cast<GLenum>(c.format); 9058 GLenum type = static_cast<GLenum>(c.type); 9059 uint32 data_size; 9060 if (!GLES2Util::ComputeImageDataSizes( 9061 width, height, format, type, state_.unpack_alignment, &data_size, 9062 NULL, NULL)) { 9063 return error::kOutOfBounds; 9064 } 9065 const void* pixels = GetSharedMemoryAs<const void*>( 9066 c.pixels_shm_id, c.pixels_shm_offset, data_size); 9067 return DoTexSubImage2D( 9068 target, level, xoffset, yoffset, width, height, format, type, pixels); 9069 } 9070 9071 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( 9072 uint32 immediate_data_size, 9073 const void* cmd_data) { 9074 const gles2::cmds::GetVertexAttribPointerv& c = 9075 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data); 9076 GLuint index = static_cast<GLuint>(c.index); 9077 GLenum pname = static_cast<GLenum>(c.pname); 9078 typedef cmds::GetVertexAttribPointerv::Result Result; 9079 Result* result = GetSharedMemoryAs<Result*>( 9080 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1)); 9081 if (!result) { 9082 return error::kOutOfBounds; 9083 } 9084 // Check that the client initialized the result. 9085 if (result->size != 0) { 9086 return error::kInvalidArguments; 9087 } 9088 if (!validators_->vertex_pointer.IsValid(pname)) { 9089 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9090 "glGetVertexAttribPointerv", pname, "pname"); 9091 return error::kNoError; 9092 } 9093 if (index >= group_->max_vertex_attribs()) { 9094 LOCAL_SET_GL_ERROR( 9095 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range."); 9096 return error::kNoError; 9097 } 9098 result->SetNumResults(1); 9099 *result->GetData() = 9100 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset(); 9101 return error::kNoError; 9102 } 9103 9104 bool GLES2DecoderImpl::GetUniformSetup( 9105 GLuint program_id, GLint fake_location, 9106 uint32 shm_id, uint32 shm_offset, 9107 error::Error* error, GLint* real_location, 9108 GLuint* service_id, void** result_pointer, GLenum* result_type) { 9109 DCHECK(error); 9110 DCHECK(service_id); 9111 DCHECK(result_pointer); 9112 DCHECK(result_type); 9113 DCHECK(real_location); 9114 *error = error::kNoError; 9115 // Make sure we have enough room for the result on failure. 9116 SizedResult<GLint>* result; 9117 result = GetSharedMemoryAs<SizedResult<GLint>*>( 9118 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0)); 9119 if (!result) { 9120 *error = error::kOutOfBounds; 9121 return false; 9122 } 9123 *result_pointer = result; 9124 // Set the result size to 0 so the client does not have to check for success. 9125 result->SetNumResults(0); 9126 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform"); 9127 if (!program) { 9128 return false; 9129 } 9130 if (!program->IsValid()) { 9131 // Program was not linked successfully. (ie, glLinkProgram) 9132 LOCAL_SET_GL_ERROR( 9133 GL_INVALID_OPERATION, "glGetUniform", "program not linked"); 9134 return false; 9135 } 9136 *service_id = program->service_id(); 9137 GLint array_index = -1; 9138 const Program::UniformInfo* uniform_info = 9139 program->GetUniformInfoByFakeLocation( 9140 fake_location, real_location, &array_index); 9141 if (!uniform_info) { 9142 // No such location. 9143 LOCAL_SET_GL_ERROR( 9144 GL_INVALID_OPERATION, "glGetUniform", "unknown location"); 9145 return false; 9146 } 9147 GLenum type = uniform_info->type; 9148 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type); 9149 if (size == 0) { 9150 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type"); 9151 return false; 9152 } 9153 result = GetSharedMemoryAs<SizedResult<GLint>*>( 9154 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size)); 9155 if (!result) { 9156 *error = error::kOutOfBounds; 9157 return false; 9158 } 9159 result->size = size; 9160 *result_type = type; 9161 return true; 9162 } 9163 9164 error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size, 9165 const void* cmd_data) { 9166 const gles2::cmds::GetUniformiv& c = 9167 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data); 9168 GLuint program = c.program; 9169 GLint fake_location = c.location; 9170 GLuint service_id; 9171 GLenum result_type; 9172 GLint real_location = -1; 9173 Error error; 9174 void* result; 9175 if (GetUniformSetup( 9176 program, fake_location, c.params_shm_id, c.params_shm_offset, 9177 &error, &real_location, &service_id, &result, &result_type)) { 9178 glGetUniformiv( 9179 service_id, real_location, 9180 static_cast<cmds::GetUniformiv::Result*>(result)->GetData()); 9181 } 9182 return error; 9183 } 9184 9185 error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size, 9186 const void* cmd_data) { 9187 const gles2::cmds::GetUniformfv& c = 9188 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data); 9189 GLuint program = c.program; 9190 GLint fake_location = c.location; 9191 GLuint service_id; 9192 GLint real_location = -1; 9193 Error error; 9194 typedef cmds::GetUniformfv::Result Result; 9195 Result* result; 9196 GLenum result_type; 9197 if (GetUniformSetup( 9198 program, fake_location, c.params_shm_id, c.params_shm_offset, 9199 &error, &real_location, &service_id, 9200 reinterpret_cast<void**>(&result), &result_type)) { 9201 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 || 9202 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) { 9203 GLsizei num_values = result->GetNumResults(); 9204 scoped_ptr<GLint[]> temp(new GLint[num_values]); 9205 glGetUniformiv(service_id, real_location, temp.get()); 9206 GLfloat* dst = result->GetData(); 9207 for (GLsizei ii = 0; ii < num_values; ++ii) { 9208 dst[ii] = (temp[ii] != 0); 9209 } 9210 } else { 9211 glGetUniformfv(service_id, real_location, result->GetData()); 9212 } 9213 } 9214 return error; 9215 } 9216 9217 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( 9218 uint32 immediate_data_size, 9219 const void* cmd_data) { 9220 const gles2::cmds::GetShaderPrecisionFormat& c = 9221 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data); 9222 GLenum shader_type = static_cast<GLenum>(c.shadertype); 9223 GLenum precision_type = static_cast<GLenum>(c.precisiontype); 9224 typedef cmds::GetShaderPrecisionFormat::Result Result; 9225 Result* result = GetSharedMemoryAs<Result*>( 9226 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 9227 if (!result) { 9228 return error::kOutOfBounds; 9229 } 9230 // Check that the client initialized the result. 9231 if (result->success != 0) { 9232 return error::kInvalidArguments; 9233 } 9234 if (!validators_->shader_type.IsValid(shader_type)) { 9235 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9236 "glGetShaderPrecisionFormat", shader_type, "shader_type"); 9237 return error::kNoError; 9238 } 9239 if (!validators_->shader_precision.IsValid(precision_type)) { 9240 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9241 "glGetShaderPrecisionFormat", precision_type, "precision_type"); 9242 return error::kNoError; 9243 } 9244 9245 result->success = 1; // true 9246 9247 GLint range[2] = { 0, 0 }; 9248 GLint precision = 0; 9249 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision); 9250 9251 result->min_range = range[0]; 9252 result->max_range = range[1]; 9253 result->precision = precision; 9254 9255 return error::kNoError; 9256 } 9257 9258 error::Error GLES2DecoderImpl::HandleGetAttachedShaders( 9259 uint32 immediate_data_size, 9260 const void* cmd_data) { 9261 const gles2::cmds::GetAttachedShaders& c = 9262 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data); 9263 uint32 result_size = c.result_size; 9264 GLuint program_id = static_cast<GLuint>(c.program); 9265 Program* program = GetProgramInfoNotShader( 9266 program_id, "glGetAttachedShaders"); 9267 if (!program) { 9268 return error::kNoError; 9269 } 9270 typedef cmds::GetAttachedShaders::Result Result; 9271 uint32 max_count = Result::ComputeMaxResults(result_size); 9272 Result* result = GetSharedMemoryAs<Result*>( 9273 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count)); 9274 if (!result) { 9275 return error::kOutOfBounds; 9276 } 9277 // Check that the client initialized the result. 9278 if (result->size != 0) { 9279 return error::kInvalidArguments; 9280 } 9281 GLsizei count = 0; 9282 glGetAttachedShaders( 9283 program->service_id(), max_count, &count, result->GetData()); 9284 for (GLsizei ii = 0; ii < count; ++ii) { 9285 if (!shader_manager()->GetClientId(result->GetData()[ii], 9286 &result->GetData()[ii])) { 9287 NOTREACHED(); 9288 return error::kGenericError; 9289 } 9290 } 9291 result->SetNumResults(count); 9292 return error::kNoError; 9293 } 9294 9295 error::Error GLES2DecoderImpl::HandleGetActiveUniform( 9296 uint32 immediate_data_size, 9297 const void* cmd_data) { 9298 const gles2::cmds::GetActiveUniform& c = 9299 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data); 9300 GLuint program_id = c.program; 9301 GLuint index = c.index; 9302 uint32 name_bucket_id = c.name_bucket_id; 9303 typedef cmds::GetActiveUniform::Result Result; 9304 Result* result = GetSharedMemoryAs<Result*>( 9305 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 9306 if (!result) { 9307 return error::kOutOfBounds; 9308 } 9309 // Check that the client initialized the result. 9310 if (result->success != 0) { 9311 return error::kInvalidArguments; 9312 } 9313 Program* program = GetProgramInfoNotShader( 9314 program_id, "glGetActiveUniform"); 9315 if (!program) { 9316 return error::kNoError; 9317 } 9318 const Program::UniformInfo* uniform_info = 9319 program->GetUniformInfo(index); 9320 if (!uniform_info) { 9321 LOCAL_SET_GL_ERROR( 9322 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range"); 9323 return error::kNoError; 9324 } 9325 result->success = 1; // true. 9326 result->size = uniform_info->size; 9327 result->type = uniform_info->type; 9328 Bucket* bucket = CreateBucket(name_bucket_id); 9329 bucket->SetFromString(uniform_info->name.c_str()); 9330 return error::kNoError; 9331 } 9332 9333 error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size, 9334 const void* cmd_data) { 9335 const gles2::cmds::GetActiveAttrib& c = 9336 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data); 9337 GLuint program_id = c.program; 9338 GLuint index = c.index; 9339 uint32 name_bucket_id = c.name_bucket_id; 9340 typedef cmds::GetActiveAttrib::Result Result; 9341 Result* result = GetSharedMemoryAs<Result*>( 9342 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 9343 if (!result) { 9344 return error::kOutOfBounds; 9345 } 9346 // Check that the client initialized the result. 9347 if (result->success != 0) { 9348 return error::kInvalidArguments; 9349 } 9350 Program* program = GetProgramInfoNotShader( 9351 program_id, "glGetActiveAttrib"); 9352 if (!program) { 9353 return error::kNoError; 9354 } 9355 const Program::VertexAttrib* attrib_info = 9356 program->GetAttribInfo(index); 9357 if (!attrib_info) { 9358 LOCAL_SET_GL_ERROR( 9359 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range"); 9360 return error::kNoError; 9361 } 9362 result->success = 1; // true. 9363 result->size = attrib_info->size; 9364 result->type = attrib_info->type; 9365 Bucket* bucket = CreateBucket(name_bucket_id); 9366 bucket->SetFromString(attrib_info->name.c_str()); 9367 return error::kNoError; 9368 } 9369 9370 error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size, 9371 const void* cmd_data) { 9372 #if 1 // No binary shader support. 9373 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported"); 9374 return error::kNoError; 9375 #else 9376 GLsizei n = static_cast<GLsizei>(c.n); 9377 if (n < 0) { 9378 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0"); 9379 return error::kNoError; 9380 } 9381 GLsizei length = static_cast<GLsizei>(c.length); 9382 if (length < 0) { 9383 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0"); 9384 return error::kNoError; 9385 } 9386 uint32 data_size; 9387 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 9388 return error::kOutOfBounds; 9389 } 9390 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>( 9391 c.shaders_shm_id, c.shaders_shm_offset, data_size); 9392 GLenum binaryformat = static_cast<GLenum>(c.binaryformat); 9393 const void* binary = GetSharedMemoryAs<const void*>( 9394 c.binary_shm_id, c.binary_shm_offset, length); 9395 if (shaders == NULL || binary == NULL) { 9396 return error::kOutOfBounds; 9397 } 9398 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 9399 for (GLsizei ii = 0; ii < n; ++ii) { 9400 Shader* shader = GetShader(shaders[ii]); 9401 if (!shader) { 9402 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader"); 9403 return error::kNoError; 9404 } 9405 service_ids[ii] = shader->service_id(); 9406 } 9407 // TODO(gman): call glShaderBinary 9408 return error::kNoError; 9409 #endif 9410 } 9411 9412 void GLES2DecoderImpl::DoSwapBuffers() { 9413 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 9414 9415 int this_frame_number = frame_number_++; 9416 // TRACE_EVENT for gpu tests: 9417 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency", 9418 TRACE_EVENT_SCOPE_THREAD, 9419 "GLImpl", static_cast<int>(gfx::GetGLImplementation()), 9420 "width", (is_offscreen ? offscreen_size_.width() : 9421 surface_->GetSize().width())); 9422 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers", 9423 "offscreen", is_offscreen, 9424 "frame", this_frame_number); 9425 { 9426 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame"); 9427 } 9428 9429 bool is_tracing; 9430 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), 9431 &is_tracing); 9432 if (is_tracing) { 9433 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); 9434 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( 9435 is_offscreen ? offscreen_size_ : surface_->GetSize()); 9436 } 9437 9438 // If offscreen then don't actually SwapBuffers to the display. Just copy 9439 // the rendered frame to another frame buffer. 9440 if (is_offscreen) { 9441 TRACE_EVENT2("gpu", "Offscreen", 9442 "width", offscreen_size_.width(), "height", offscreen_size_.height()); 9443 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { 9444 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, 9445 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will 9446 // fix this. 9447 if (workarounds().needs_offscreen_buffer_workaround) { 9448 offscreen_saved_frame_buffer_->Create(); 9449 glFinish(); 9450 } 9451 9452 // Allocate the offscreen saved color texture. 9453 DCHECK(offscreen_saved_color_format_); 9454 offscreen_saved_color_texture_->AllocateStorage( 9455 offscreen_size_, offscreen_saved_color_format_, false); 9456 9457 offscreen_saved_frame_buffer_->AttachRenderTexture( 9458 offscreen_saved_color_texture_.get()); 9459 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) { 9460 if (offscreen_saved_frame_buffer_->CheckStatus() != 9461 GL_FRAMEBUFFER_COMPLETE) { 9462 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 9463 << "because offscreen saved FBO was incomplete."; 9464 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); 9465 return; 9466 } 9467 9468 // Clear the offscreen color texture. 9469 // TODO(piman): Is this still necessary? 9470 { 9471 ScopedFrameBufferBinder binder(this, 9472 offscreen_saved_frame_buffer_->id()); 9473 glClearColor(0, 0, 0, 0); 9474 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 9475 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 9476 glClear(GL_COLOR_BUFFER_BIT); 9477 RestoreClearState(); 9478 } 9479 } 9480 9481 UpdateParentTextureInfo(); 9482 } 9483 9484 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0) 9485 return; 9486 ScopedGLErrorSuppressor suppressor( 9487 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState()); 9488 9489 if (IsOffscreenBufferMultisampled()) { 9490 // For multisampled buffers, resolve the frame buffer. 9491 ScopedResolvedFrameBufferBinder binder(this, true, false); 9492 } else { 9493 ScopedFrameBufferBinder binder(this, 9494 offscreen_target_frame_buffer_->id()); 9495 9496 if (offscreen_target_buffer_preserved_) { 9497 // Copy the target frame buffer to the saved offscreen texture. 9498 offscreen_saved_color_texture_->Copy( 9499 offscreen_saved_color_texture_->size(), 9500 offscreen_saved_color_format_); 9501 } else { 9502 // Flip the textures in the parent context via the texture manager. 9503 if (!!offscreen_saved_color_texture_info_.get()) 9504 offscreen_saved_color_texture_info_->texture()-> 9505 SetServiceId(offscreen_target_color_texture_->id()); 9506 9507 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_); 9508 offscreen_target_frame_buffer_->AttachRenderTexture( 9509 offscreen_target_color_texture_.get()); 9510 } 9511 9512 // Ensure the side effects of the copy are visible to the parent 9513 // context. There is no need to do this for ANGLE because it uses a 9514 // single D3D device for all contexts. 9515 if (!feature_info_->feature_flags().is_angle) 9516 glFlush(); 9517 } 9518 } else { 9519 if (!surface_->SwapBuffers()) { 9520 LOG(ERROR) << "Context lost because SwapBuffers failed."; 9521 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); 9522 } 9523 } 9524 9525 // This may be a slow command. Exit command processing to allow for 9526 // context preemption and GPU watchdog checks. 9527 ExitCommandProcessingEarly(); 9528 } 9529 9530 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM( 9531 uint32 immediate_data_size, 9532 const void* cmd_data) { 9533 const gles2::cmds::EnableFeatureCHROMIUM& c = 9534 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data); 9535 Bucket* bucket = GetBucket(c.bucket_id); 9536 if (!bucket || bucket->size() == 0) { 9537 return error::kInvalidArguments; 9538 } 9539 typedef cmds::EnableFeatureCHROMIUM::Result Result; 9540 Result* result = GetSharedMemoryAs<Result*>( 9541 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 9542 if (!result) { 9543 return error::kOutOfBounds; 9544 } 9545 // Check that the client initialized the result. 9546 if (*result != 0) { 9547 return error::kInvalidArguments; 9548 } 9549 std::string feature_str; 9550 if (!bucket->GetAsString(&feature_str)) { 9551 return error::kInvalidArguments; 9552 } 9553 9554 // TODO(gman): make this some kind of table to function pointer thingy. 9555 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) { 9556 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 9557 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) { 9558 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 9559 // TODO(gman): decide how to remove the need for this const_cast. 9560 // I could make validators_ non const but that seems bad as this is the only 9561 // place it is needed. I could make some special friend class of validators 9562 // just to allow this to set them. That seems silly. I could refactor this 9563 // code to use the extension mechanism or the initialization attributes to 9564 // turn this feature on. Given that the only real point of this is to make 9565 // the conformance tests pass and given that there is lots of real work that 9566 // needs to be done it seems like refactoring for one to one of those 9567 // methods is a very low priority. 9568 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED); 9569 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) { 9570 force_webgl_glsl_validation_ = true; 9571 InitializeShaderTranslator(); 9572 } else { 9573 return error::kNoError; 9574 } 9575 9576 *result = 1; // true. 9577 return error::kNoError; 9578 } 9579 9580 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM( 9581 uint32 immediate_data_size, 9582 const void* cmd_data) { 9583 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c = 9584 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>( 9585 cmd_data); 9586 Bucket* bucket = CreateBucket(c.bucket_id); 9587 scoped_refptr<FeatureInfo> info(new FeatureInfo()); 9588 info->Initialize(disallowed_features_); 9589 bucket->SetFromString(info->extensions().c_str()); 9590 return error::kNoError; 9591 } 9592 9593 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM( 9594 uint32 immediate_data_size, 9595 const void* cmd_data) { 9596 const gles2::cmds::RequestExtensionCHROMIUM& c = 9597 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data); 9598 Bucket* bucket = GetBucket(c.bucket_id); 9599 if (!bucket || bucket->size() == 0) { 9600 return error::kInvalidArguments; 9601 } 9602 std::string feature_str; 9603 if (!bucket->GetAsString(&feature_str)) { 9604 return error::kInvalidArguments; 9605 } 9606 9607 bool desire_webgl_glsl_validation = 9608 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos; 9609 bool desire_standard_derivatives = false; 9610 bool desire_frag_depth = false; 9611 bool desire_draw_buffers = false; 9612 bool desire_shader_texture_lod = false; 9613 if (force_webgl_glsl_validation_) { 9614 desire_standard_derivatives = 9615 feature_str.find("GL_OES_standard_derivatives") != std::string::npos; 9616 desire_frag_depth = 9617 feature_str.find("GL_EXT_frag_depth") != std::string::npos; 9618 desire_draw_buffers = 9619 feature_str.find("GL_EXT_draw_buffers") != std::string::npos; 9620 desire_shader_texture_lod = 9621 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos; 9622 } 9623 9624 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ || 9625 desire_standard_derivatives != derivatives_explicitly_enabled_ || 9626 desire_frag_depth != frag_depth_explicitly_enabled_ || 9627 desire_draw_buffers != draw_buffers_explicitly_enabled_) { 9628 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation; 9629 derivatives_explicitly_enabled_ |= desire_standard_derivatives; 9630 frag_depth_explicitly_enabled_ |= desire_frag_depth; 9631 draw_buffers_explicitly_enabled_ |= desire_draw_buffers; 9632 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod; 9633 InitializeShaderTranslator(); 9634 } 9635 9636 UpdateCapabilities(); 9637 9638 return error::kNoError; 9639 } 9640 9641 error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( 9642 uint32 immediate_data_size, 9643 const void* cmd_data) { 9644 const gles2::cmds::GetMultipleIntegervCHROMIUM& c = 9645 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data); 9646 GLuint count = c.count; 9647 uint32 pnames_size; 9648 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) { 9649 return error::kOutOfBounds; 9650 } 9651 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>( 9652 c.pnames_shm_id, c.pnames_shm_offset, pnames_size); 9653 if (pnames == NULL) { 9654 return error::kOutOfBounds; 9655 } 9656 9657 // We have to copy them since we use them twice so the client 9658 // can't change them between the time we validate them and the time we use 9659 // them. 9660 scoped_ptr<GLenum[]> enums(new GLenum[count]); 9661 memcpy(enums.get(), pnames, pnames_size); 9662 9663 // Count up the space needed for the result. 9664 uint32 num_results = 0; 9665 for (GLuint ii = 0; ii < count; ++ii) { 9666 uint32 num = util_.GLGetNumValuesReturned(enums[ii]); 9667 if (num == 0) { 9668 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9669 "glGetMultipleCHROMIUM", enums[ii], "pname"); 9670 return error::kNoError; 9671 } 9672 // Num will never be more than 4. 9673 DCHECK_LE(num, 4u); 9674 if (!SafeAddUint32(num_results, num, &num_results)) { 9675 return error::kOutOfBounds; 9676 } 9677 } 9678 9679 uint32 result_size = 0; 9680 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) { 9681 return error::kOutOfBounds; 9682 } 9683 9684 if (result_size != static_cast<uint32>(c.size)) { 9685 LOCAL_SET_GL_ERROR( 9686 GL_INVALID_VALUE, 9687 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE"); 9688 return error::kNoError; 9689 } 9690 9691 GLint* results = GetSharedMemoryAs<GLint*>( 9692 c.results_shm_id, c.results_shm_offset, result_size); 9693 if (results == NULL) { 9694 return error::kOutOfBounds; 9695 } 9696 9697 // Check the results have been cleared in case the context was lost. 9698 for (uint32 ii = 0; ii < num_results; ++ii) { 9699 if (results[ii]) { 9700 return error::kInvalidArguments; 9701 } 9702 } 9703 9704 // Get each result. 9705 GLint* start = results; 9706 for (GLuint ii = 0; ii < count; ++ii) { 9707 GLsizei num_written = 0; 9708 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) && 9709 !GetHelper(enums[ii], results, &num_written)) { 9710 DoGetIntegerv(enums[ii], results); 9711 } 9712 results += num_written; 9713 } 9714 9715 // Just to verify. Should this be a DCHECK? 9716 if (static_cast<uint32>(results - start) != num_results) { 9717 return error::kOutOfBounds; 9718 } 9719 9720 return error::kNoError; 9721 } 9722 9723 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM( 9724 uint32 immediate_data_size, 9725 const void* cmd_data) { 9726 const gles2::cmds::GetProgramInfoCHROMIUM& c = 9727 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data); 9728 GLuint program_id = static_cast<GLuint>(c.program); 9729 uint32 bucket_id = c.bucket_id; 9730 Bucket* bucket = CreateBucket(bucket_id); 9731 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail. 9732 Program* program = NULL; 9733 program = GetProgram(program_id); 9734 if (!program || !program->IsValid()) { 9735 return error::kNoError; 9736 } 9737 program->GetProgramInfo(program_manager(), bucket); 9738 return error::kNoError; 9739 } 9740 9741 error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { 9742 switch (reset_status_) { 9743 case GL_NO_ERROR: 9744 // TODO(kbr): improve the precision of the error code in this case. 9745 // Consider delegating to context for error code if MakeCurrent fails. 9746 return error::kUnknown; 9747 case GL_GUILTY_CONTEXT_RESET_ARB: 9748 return error::kGuilty; 9749 case GL_INNOCENT_CONTEXT_RESET_ARB: 9750 return error::kInnocent; 9751 case GL_UNKNOWN_CONTEXT_RESET_ARB: 9752 return error::kUnknown; 9753 } 9754 9755 NOTREACHED(); 9756 return error::kUnknown; 9757 } 9758 9759 bool GLES2DecoderImpl::WasContextLost() { 9760 if (reset_status_ != GL_NO_ERROR) { 9761 return true; 9762 } 9763 if (context_->WasAllocatedUsingRobustnessExtension()) { 9764 GLenum status = GL_NO_ERROR; 9765 if (has_robustness_extension_) 9766 status = glGetGraphicsResetStatusARB(); 9767 if (status != GL_NO_ERROR) { 9768 // The graphics card was reset. Signal a lost context to the application. 9769 reset_status_ = status; 9770 reset_by_robustness_extension_ = true; 9771 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen") 9772 << " context lost via ARB/EXT_robustness. Reset status = " 9773 << GLES2Util::GetStringEnum(status); 9774 return true; 9775 } 9776 } 9777 return false; 9778 } 9779 9780 bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() { 9781 return WasContextLost() && reset_by_robustness_extension_; 9782 } 9783 9784 void GLES2DecoderImpl::LoseContext(uint32 reset_status) { 9785 // Only loses the context once. 9786 if (reset_status_ != GL_NO_ERROR) { 9787 return; 9788 } 9789 9790 // Marks this context as lost. 9791 reset_status_ = reset_status; 9792 current_decoder_error_ = error::kLostContext; 9793 } 9794 9795 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM( 9796 uint32 immediate_data_size, 9797 const void* cmd_data) { 9798 return error::kUnknownCommand; 9799 } 9800 9801 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM( 9802 uint32 immediate_data_size, 9803 const void* cmd_data) { 9804 const gles2::cmds::WaitSyncPointCHROMIUM& c = 9805 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data); 9806 uint32 sync_point = c.sync_point; 9807 if (wait_sync_point_callback_.is_null()) 9808 return error::kNoError; 9809 9810 return wait_sync_point_callback_.Run(sync_point) ? 9811 error::kNoError : error::kDeferCommandUntilLater; 9812 } 9813 9814 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( 9815 uint32 immediate_data_size, 9816 const void* cmd_data) { 9817 if (surface_->DeferDraws()) 9818 return error::kDeferCommandUntilLater; 9819 if (!surface_->SetBackbufferAllocation(false)) 9820 return error::kLostContext; 9821 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT; 9822 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT; 9823 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT; 9824 return error::kNoError; 9825 } 9826 9827 bool GLES2DecoderImpl::GenQueriesEXTHelper( 9828 GLsizei n, const GLuint* client_ids) { 9829 for (GLsizei ii = 0; ii < n; ++ii) { 9830 if (query_manager_->GetQuery(client_ids[ii])) { 9831 return false; 9832 } 9833 } 9834 query_manager_->GenQueries(n, client_ids); 9835 return true; 9836 } 9837 9838 void GLES2DecoderImpl::DeleteQueriesEXTHelper( 9839 GLsizei n, const GLuint* client_ids) { 9840 for (GLsizei ii = 0; ii < n; ++ii) { 9841 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]); 9842 if (query && !query->IsDeleted()) { 9843 ContextState::QueryMap::iterator it = 9844 state_.current_queries.find(query->target()); 9845 if (it != state_.current_queries.end()) 9846 state_.current_queries.erase(it); 9847 9848 query->Destroy(true); 9849 } 9850 query_manager_->RemoveQuery(client_ids[ii]); 9851 } 9852 } 9853 9854 bool GLES2DecoderImpl::ProcessPendingQueries() { 9855 if (query_manager_.get() == NULL) { 9856 return false; 9857 } 9858 if (!query_manager_->ProcessPendingQueries()) { 9859 current_decoder_error_ = error::kOutOfBounds; 9860 } 9861 return query_manager_->HavePendingQueries(); 9862 } 9863 9864 // Note that if there are no pending readpixels right now, 9865 // this function will call the callback immediately. 9866 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) { 9867 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) { 9868 pending_readpixel_fences_.back()->callbacks.push_back(callback); 9869 } else { 9870 callback.Run(); 9871 } 9872 } 9873 9874 void GLES2DecoderImpl::ProcessPendingReadPixels() { 9875 while (!pending_readpixel_fences_.empty() && 9876 pending_readpixel_fences_.front()->fence->HasCompleted()) { 9877 std::vector<base::Closure> callbacks = 9878 pending_readpixel_fences_.front()->callbacks; 9879 pending_readpixel_fences_.pop(); 9880 for (size_t i = 0; i < callbacks.size(); i++) { 9881 callbacks[i].Run(); 9882 } 9883 } 9884 } 9885 9886 bool GLES2DecoderImpl::HasMoreIdleWork() { 9887 return !pending_readpixel_fences_.empty() || 9888 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); 9889 } 9890 9891 void GLES2DecoderImpl::PerformIdleWork() { 9892 ProcessPendingReadPixels(); 9893 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) 9894 return; 9895 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); 9896 ProcessFinishedAsyncTransfers(); 9897 } 9898 9899 error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size, 9900 const void* cmd_data) { 9901 const gles2::cmds::BeginQueryEXT& c = 9902 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data); 9903 GLenum target = static_cast<GLenum>(c.target); 9904 GLuint client_id = static_cast<GLuint>(c.id); 9905 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); 9906 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 9907 9908 switch (target) { 9909 case GL_COMMANDS_ISSUED_CHROMIUM: 9910 case GL_LATENCY_QUERY_CHROMIUM: 9911 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM: 9912 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: 9913 case GL_GET_ERROR_QUERY_CHROMIUM: 9914 break; 9915 case GL_COMMANDS_COMPLETED_CHROMIUM: 9916 if (!features().chromium_sync_query) { 9917 LOCAL_SET_GL_ERROR( 9918 GL_INVALID_OPERATION, "glBeginQueryEXT", 9919 "not enabled for commands completed queries"); 9920 return error::kNoError; 9921 } 9922 break; 9923 default: 9924 if (!features().occlusion_query_boolean) { 9925 LOCAL_SET_GL_ERROR( 9926 GL_INVALID_OPERATION, "glBeginQueryEXT", 9927 "not enabled for occlusion queries"); 9928 return error::kNoError; 9929 } 9930 break; 9931 } 9932 9933 if (state_.current_queries.find(target) != state_.current_queries.end()) { 9934 LOCAL_SET_GL_ERROR( 9935 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); 9936 return error::kNoError; 9937 } 9938 9939 if (client_id == 0) { 9940 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); 9941 return error::kNoError; 9942 } 9943 9944 QueryManager::Query* query = query_manager_->GetQuery(client_id); 9945 if (!query) { 9946 if (!query_manager_->IsValidQuery(client_id)) { 9947 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 9948 "glBeginQueryEXT", 9949 "id not made by glGenQueriesEXT"); 9950 return error::kNoError; 9951 } 9952 query = query_manager_->CreateQuery( 9953 target, client_id, sync_shm_id, sync_shm_offset); 9954 } 9955 9956 if (query->target() != target) { 9957 LOCAL_SET_GL_ERROR( 9958 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match"); 9959 return error::kNoError; 9960 } else if (query->shm_id() != sync_shm_id || 9961 query->shm_offset() != sync_shm_offset) { 9962 DLOG(ERROR) << "Shared memory used by query not the same as before"; 9963 return error::kInvalidArguments; 9964 } 9965 9966 if (!query_manager_->BeginQuery(query)) { 9967 return error::kOutOfBounds; 9968 } 9969 9970 state_.current_queries[target] = query; 9971 return error::kNoError; 9972 } 9973 9974 error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size, 9975 const void* cmd_data) { 9976 const gles2::cmds::EndQueryEXT& c = 9977 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data); 9978 GLenum target = static_cast<GLenum>(c.target); 9979 uint32 submit_count = static_cast<GLuint>(c.submit_count); 9980 ContextState::QueryMap::iterator it = state_.current_queries.find(target); 9981 9982 if (it == state_.current_queries.end()) { 9983 LOCAL_SET_GL_ERROR( 9984 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query"); 9985 return error::kNoError; 9986 } 9987 9988 QueryManager::Query* query = it->second.get(); 9989 if (!query_manager_->EndQuery(query, submit_count)) { 9990 return error::kOutOfBounds; 9991 } 9992 9993 query_manager_->ProcessPendingTransferQueries(); 9994 9995 state_.current_queries.erase(it); 9996 return error::kNoError; 9997 } 9998 9999 bool GLES2DecoderImpl::GenVertexArraysOESHelper( 10000 GLsizei n, const GLuint* client_ids) { 10001 for (GLsizei ii = 0; ii < n; ++ii) { 10002 if (GetVertexAttribManager(client_ids[ii])) { 10003 return false; 10004 } 10005 } 10006 10007 if (!features().native_vertex_array_object) { 10008 // Emulated VAO 10009 for (GLsizei ii = 0; ii < n; ++ii) { 10010 CreateVertexAttribManager(client_ids[ii], 0, true); 10011 } 10012 } else { 10013 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 10014 10015 glGenVertexArraysOES(n, service_ids.get()); 10016 for (GLsizei ii = 0; ii < n; ++ii) { 10017 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true); 10018 } 10019 } 10020 10021 return true; 10022 } 10023 10024 void GLES2DecoderImpl::DeleteVertexArraysOESHelper( 10025 GLsizei n, const GLuint* client_ids) { 10026 for (GLsizei ii = 0; ii < n; ++ii) { 10027 VertexAttribManager* vao = 10028 GetVertexAttribManager(client_ids[ii]); 10029 if (vao && !vao->IsDeleted()) { 10030 if (state_.vertex_attrib_manager.get() == vao) { 10031 DoBindVertexArrayOES(0); 10032 } 10033 RemoveVertexAttribManager(client_ids[ii]); 10034 } 10035 } 10036 } 10037 10038 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) { 10039 VertexAttribManager* vao = NULL; 10040 if (client_id != 0) { 10041 vao = GetVertexAttribManager(client_id); 10042 if (!vao) { 10043 // Unlike most Bind* methods, the spec explicitly states that VertexArray 10044 // only allows names that have been previously generated. As such, we do 10045 // not generate new names here. 10046 LOCAL_SET_GL_ERROR( 10047 GL_INVALID_OPERATION, 10048 "glBindVertexArrayOES", "bad vertex array id."); 10049 current_decoder_error_ = error::kNoError; 10050 return; 10051 } 10052 } else { 10053 vao = state_.default_vertex_attrib_manager.get(); 10054 } 10055 10056 // Only set the VAO state if it's changed 10057 if (state_.vertex_attrib_manager.get() != vao) { 10058 state_.vertex_attrib_manager = vao; 10059 if (!features().native_vertex_array_object) { 10060 EmulateVertexArrayState(); 10061 } else { 10062 GLuint service_id = vao->service_id(); 10063 glBindVertexArrayOES(service_id); 10064 } 10065 } 10066 } 10067 10068 // Used when OES_vertex_array_object isn't natively supported 10069 void GLES2DecoderImpl::EmulateVertexArrayState() { 10070 // Setup the Vertex attribute state 10071 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) { 10072 RestoreStateForAttrib(vv, true); 10073 } 10074 10075 // Setup the element buffer 10076 Buffer* element_array_buffer = 10077 state_.vertex_attrib_manager->element_array_buffer(); 10078 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 10079 element_array_buffer ? element_array_buffer->service_id() : 0); 10080 } 10081 10082 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { 10083 const VertexAttribManager* vao = 10084 GetVertexAttribManager(client_id); 10085 return vao && vao->IsValid() && !vao->IsDeleted(); 10086 } 10087 10088 #if defined(OS_MACOSX) 10089 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { 10090 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( 10091 texture_id); 10092 if (it != texture_to_io_surface_map_.end()) { 10093 // Found a previous IOSurface bound to this texture; release it. 10094 IOSurfaceRef surface = it->second; 10095 CFRelease(surface); 10096 texture_to_io_surface_map_.erase(it); 10097 } 10098 } 10099 #endif 10100 10101 void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM( 10102 GLenum target, GLsizei width, GLsizei height, 10103 GLuint io_surface_id, GLuint plane) { 10104 #if defined(OS_MACOSX) 10105 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { 10106 LOCAL_SET_GL_ERROR( 10107 GL_INVALID_OPERATION, 10108 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL."); 10109 return; 10110 } 10111 10112 if (target != GL_TEXTURE_RECTANGLE_ARB) { 10113 // This might be supported in the future, and if we could require 10114 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we 10115 // could delete a lot of code. For now, perform strict validation so we 10116 // know what's going on. 10117 LOCAL_SET_GL_ERROR( 10118 GL_INVALID_OPERATION, 10119 "glTexImageIOSurface2DCHROMIUM", 10120 "requires TEXTURE_RECTANGLE_ARB target"); 10121 return; 10122 } 10123 10124 // Default target might be conceptually valid, but disallow it to avoid 10125 // accidents. 10126 TextureRef* texture_ref = 10127 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); 10128 if (!texture_ref) { 10129 LOCAL_SET_GL_ERROR( 10130 GL_INVALID_OPERATION, 10131 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound"); 10132 return; 10133 } 10134 10135 // Look up the new IOSurface. Note that because of asynchrony 10136 // between processes this might fail; during live resizing the 10137 // plugin process might allocate and release an IOSurface before 10138 // this process gets a chance to look it up. Hold on to any old 10139 // IOSurface in this case. 10140 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id); 10141 if (!surface) { 10142 LOCAL_SET_GL_ERROR( 10143 GL_INVALID_OPERATION, 10144 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID"); 10145 return; 10146 } 10147 10148 // Release any IOSurface previously bound to this texture. 10149 ReleaseIOSurfaceForTexture(texture_ref->service_id()); 10150 10151 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails. 10152 texture_to_io_surface_map_.insert( 10153 std::make_pair(texture_ref->service_id(), surface)); 10154 10155 CGLContextObj context = 10156 static_cast<CGLContextObj>(context_->GetHandle()); 10157 10158 CGLError err = CGLTexImageIOSurface2D( 10159 context, 10160 target, 10161 GL_RGBA, 10162 width, 10163 height, 10164 GL_BGRA, 10165 GL_UNSIGNED_INT_8_8_8_8_REV, 10166 surface, 10167 plane); 10168 10169 if (err != kCGLNoError) { 10170 LOCAL_SET_GL_ERROR( 10171 GL_INVALID_OPERATION, 10172 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D"); 10173 return; 10174 } 10175 10176 texture_manager()->SetLevelInfo( 10177 texture_ref, target, 0, GL_RGBA, width, height, 1, 0, 10178 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); 10179 10180 #else 10181 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10182 "glTexImageIOSurface2DCHROMIUM", "not supported."); 10183 #endif 10184 } 10185 10186 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { 10187 switch (internalformat) { 10188 case GL_RGB565: 10189 return GL_RGB; 10190 case GL_RGBA4: 10191 return GL_RGBA; 10192 case GL_RGB5_A1: 10193 return GL_RGBA; 10194 case GL_RGB8_OES: 10195 return GL_RGB; 10196 case GL_RGBA8_OES: 10197 return GL_RGBA; 10198 case GL_LUMINANCE8_ALPHA8_EXT: 10199 return GL_LUMINANCE_ALPHA; 10200 case GL_LUMINANCE8_EXT: 10201 return GL_LUMINANCE; 10202 case GL_ALPHA8_EXT: 10203 return GL_ALPHA; 10204 case GL_RGBA32F_EXT: 10205 return GL_RGBA; 10206 case GL_RGB32F_EXT: 10207 return GL_RGB; 10208 case GL_ALPHA32F_EXT: 10209 return GL_ALPHA; 10210 case GL_LUMINANCE32F_EXT: 10211 return GL_LUMINANCE; 10212 case GL_LUMINANCE_ALPHA32F_EXT: 10213 return GL_LUMINANCE_ALPHA; 10214 case GL_RGBA16F_EXT: 10215 return GL_RGBA; 10216 case GL_RGB16F_EXT: 10217 return GL_RGB; 10218 case GL_ALPHA16F_EXT: 10219 return GL_ALPHA; 10220 case GL_LUMINANCE16F_EXT: 10221 return GL_LUMINANCE; 10222 case GL_LUMINANCE_ALPHA16F_EXT: 10223 return GL_LUMINANCE_ALPHA; 10224 case GL_BGRA8_EXT: 10225 return GL_BGRA_EXT; 10226 default: 10227 return GL_NONE; 10228 } 10229 } 10230 10231 void GLES2DecoderImpl::DoCopyTextureCHROMIUM( 10232 GLenum target, GLuint source_id, GLuint dest_id, GLint level, 10233 GLenum internal_format, GLenum dest_type) { 10234 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); 10235 10236 TextureRef* dest_texture_ref = GetTexture(dest_id); 10237 TextureRef* source_texture_ref = GetTexture(source_id); 10238 10239 if (!source_texture_ref || !dest_texture_ref) { 10240 LOCAL_SET_GL_ERROR( 10241 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id"); 10242 return; 10243 } 10244 10245 if (GL_TEXTURE_2D != target) { 10246 LOCAL_SET_GL_ERROR( 10247 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target"); 10248 return; 10249 } 10250 10251 Texture* source_texture = source_texture_ref->texture(); 10252 Texture* dest_texture = dest_texture_ref->texture(); 10253 if (dest_texture->target() != GL_TEXTURE_2D || 10254 (source_texture->target() != GL_TEXTURE_2D && 10255 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB && 10256 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) { 10257 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, 10258 "glCopyTextureCHROMIUM", 10259 "invalid texture target binding"); 10260 return; 10261 } 10262 10263 int source_width, source_height, dest_width, dest_height; 10264 10265 gfx::GLImage* image = 10266 source_texture->GetLevelImage(source_texture->target(), 0); 10267 if (image) { 10268 gfx::Size size = image->GetSize(); 10269 source_width = size.width(); 10270 source_height = size.height(); 10271 if (source_width <= 0 || source_height <= 0) { 10272 LOCAL_SET_GL_ERROR( 10273 GL_INVALID_VALUE, 10274 "glCopyTextureChromium", "invalid image size"); 10275 return; 10276 } 10277 } else { 10278 if (!source_texture->GetLevelSize( 10279 source_texture->target(), 0, &source_width, &source_height)) { 10280 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, 10281 "glCopyTextureChromium", 10282 "source texture has no level 0"); 10283 return; 10284 } 10285 10286 // Check that this type of texture is allowed. 10287 if (!texture_manager()->ValidForTarget( 10288 source_texture->target(), level, source_width, source_height, 1)) { 10289 LOCAL_SET_GL_ERROR( 10290 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions"); 10291 return; 10292 } 10293 } 10294 10295 // Clear the source texture if necessary. 10296 if (!texture_manager()->ClearTextureLevel( 10297 this, source_texture_ref, source_texture->target(), 0)) { 10298 LOCAL_SET_GL_ERROR( 10299 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big"); 10300 return; 10301 } 10302 10303 GLenum source_type = 0; 10304 GLenum source_internal_format = 0; 10305 source_texture->GetLevelType( 10306 source_texture->target(), 0, &source_type, &source_internal_format); 10307 10308 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA, 10309 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not 10310 // renderable on some platforms. 10311 bool valid_dest_format = internal_format == GL_RGB || 10312 internal_format == GL_RGBA || 10313 internal_format == GL_BGRA_EXT; 10314 bool valid_source_format = source_internal_format == GL_ALPHA || 10315 source_internal_format == GL_RGB || 10316 source_internal_format == GL_RGBA || 10317 source_internal_format == GL_LUMINANCE || 10318 source_internal_format == GL_LUMINANCE_ALPHA || 10319 source_internal_format == GL_BGRA_EXT; 10320 if (!valid_source_format || !valid_dest_format) { 10321 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10322 "glCopyTextureCHROMIUM", 10323 "invalid internal format"); 10324 return; 10325 } 10326 10327 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is 10328 // needed because it takes 10s of milliseconds to initialize. 10329 if (!copy_texture_CHROMIUM_.get()) { 10330 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); 10331 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); 10332 copy_texture_CHROMIUM_->Initialize(this); 10333 RestoreCurrentFramebufferBindings(); 10334 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR) 10335 return; 10336 } 10337 10338 GLenum dest_type_previous = dest_type; 10339 GLenum dest_internal_format = internal_format; 10340 bool dest_level_defined = dest_texture->GetLevelSize( 10341 GL_TEXTURE_2D, level, &dest_width, &dest_height); 10342 10343 if (dest_level_defined) { 10344 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous, 10345 &dest_internal_format); 10346 } 10347 10348 // Resize the destination texture to the dimensions of the source texture. 10349 if (!dest_level_defined || dest_width != source_width || 10350 dest_height != source_height || 10351 dest_internal_format != internal_format || 10352 dest_type_previous != dest_type) { 10353 // Ensure that the glTexImage2D succeeds. 10354 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); 10355 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); 10356 glTexImage2D( 10357 GL_TEXTURE_2D, level, internal_format, source_width, source_height, 10358 0, internal_format, dest_type, NULL); 10359 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); 10360 if (error != GL_NO_ERROR) { 10361 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D); 10362 return; 10363 } 10364 10365 texture_manager()->SetLevelInfo( 10366 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width, 10367 source_height, 1, 0, internal_format, dest_type, true); 10368 } else { 10369 texture_manager()->SetLevelCleared( 10370 dest_texture_ref, GL_TEXTURE_2D, level, true); 10371 } 10372 10373 ScopedModifyPixels modify(dest_texture_ref); 10374 10375 // Try using GLImage::CopyTexImage when possible. 10376 bool unpack_premultiply_alpha_change = 10377 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_; 10378 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) { 10379 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); 10380 if (image->CopyTexImage(GL_TEXTURE_2D)) 10381 return; 10382 } 10383 10384 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); 10385 10386 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix 10387 // before presenting. 10388 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { 10389 // TODO(hkuang): get the StreamTexture transform matrix in GPU process 10390 // instead of using default matrix crbug.com/226218. 10391 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 10392 0.0f, 1.0f, 0.0f, 0.0f, 10393 0.0f, 0.0f, 1.0f, 0.0f, 10394 0.0f, 0.0f, 0.0f, 1.0f}; 10395 copy_texture_CHROMIUM_->DoCopyTextureWithTransform( 10396 this, 10397 source_texture->target(), 10398 source_texture->service_id(), 10399 dest_texture->service_id(), 10400 level, 10401 source_width, 10402 source_height, 10403 unpack_flip_y_, 10404 unpack_premultiply_alpha_, 10405 unpack_unpremultiply_alpha_, 10406 default_matrix); 10407 } else { 10408 copy_texture_CHROMIUM_->DoCopyTexture(this, 10409 source_texture->target(), 10410 source_texture->service_id(), 10411 source_internal_format, 10412 dest_texture->service_id(), 10413 level, 10414 internal_format, 10415 source_width, 10416 source_height, 10417 unpack_flip_y_, 10418 unpack_premultiply_alpha_, 10419 unpack_unpremultiply_alpha_); 10420 } 10421 10422 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); 10423 } 10424 10425 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { 10426 switch (internalformat) { 10427 case GL_RGB565: 10428 return GL_UNSIGNED_SHORT_5_6_5; 10429 case GL_RGBA4: 10430 return GL_UNSIGNED_SHORT_4_4_4_4; 10431 case GL_RGB5_A1: 10432 return GL_UNSIGNED_SHORT_5_5_5_1; 10433 case GL_RGB8_OES: 10434 return GL_UNSIGNED_BYTE; 10435 case GL_RGBA8_OES: 10436 return GL_UNSIGNED_BYTE; 10437 case GL_LUMINANCE8_ALPHA8_EXT: 10438 return GL_UNSIGNED_BYTE; 10439 case GL_LUMINANCE8_EXT: 10440 return GL_UNSIGNED_BYTE; 10441 case GL_ALPHA8_EXT: 10442 return GL_UNSIGNED_BYTE; 10443 case GL_RGBA32F_EXT: 10444 return GL_FLOAT; 10445 case GL_RGB32F_EXT: 10446 return GL_FLOAT; 10447 case GL_ALPHA32F_EXT: 10448 return GL_FLOAT; 10449 case GL_LUMINANCE32F_EXT: 10450 return GL_FLOAT; 10451 case GL_LUMINANCE_ALPHA32F_EXT: 10452 return GL_FLOAT; 10453 case GL_RGBA16F_EXT: 10454 return GL_HALF_FLOAT_OES; 10455 case GL_RGB16F_EXT: 10456 return GL_HALF_FLOAT_OES; 10457 case GL_ALPHA16F_EXT: 10458 return GL_HALF_FLOAT_OES; 10459 case GL_LUMINANCE16F_EXT: 10460 return GL_HALF_FLOAT_OES; 10461 case GL_LUMINANCE_ALPHA16F_EXT: 10462 return GL_HALF_FLOAT_OES; 10463 case GL_BGRA8_EXT: 10464 return GL_UNSIGNED_BYTE; 10465 default: 10466 return GL_NONE; 10467 } 10468 } 10469 10470 void GLES2DecoderImpl::DoTexStorage2DEXT( 10471 GLenum target, 10472 GLint levels, 10473 GLenum internal_format, 10474 GLsizei width, 10475 GLsizei height) { 10476 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT", 10477 "width", width, "height", height); 10478 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || 10479 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { 10480 LOCAL_SET_GL_ERROR( 10481 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); 10482 return; 10483 } 10484 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 10485 &state_, target); 10486 if (!texture_ref) { 10487 LOCAL_SET_GL_ERROR( 10488 GL_INVALID_OPERATION, 10489 "glTexStorage2DEXT", "unknown texture for target"); 10490 return; 10491 } 10492 Texture* texture = texture_ref->texture(); 10493 if (texture->IsAttachedToFramebuffer()) { 10494 framebuffer_state_.clear_state_dirty = true; 10495 } 10496 if (texture->IsImmutable()) { 10497 LOCAL_SET_GL_ERROR( 10498 GL_INVALID_OPERATION, 10499 "glTexStorage2DEXT", "texture is immutable"); 10500 return; 10501 } 10502 10503 GLenum format = ExtractFormatFromStorageFormat(internal_format); 10504 GLenum type = ExtractTypeFromStorageFormat(internal_format); 10505 10506 { 10507 GLsizei level_width = width; 10508 GLsizei level_height = height; 10509 uint32 estimated_size = 0; 10510 for (int ii = 0; ii < levels; ++ii) { 10511 uint32 level_size = 0; 10512 if (!GLES2Util::ComputeImageDataSizes( 10513 level_width, level_height, format, type, state_.unpack_alignment, 10514 &estimated_size, NULL, NULL) || 10515 !SafeAddUint32(estimated_size, level_size, &estimated_size)) { 10516 LOCAL_SET_GL_ERROR( 10517 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large"); 10518 return; 10519 } 10520 level_width = std::max(1, level_width >> 1); 10521 level_height = std::max(1, level_height >> 1); 10522 } 10523 if (!EnsureGPUMemoryAvailable(estimated_size)) { 10524 LOCAL_SET_GL_ERROR( 10525 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory"); 10526 return; 10527 } 10528 } 10529 10530 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); 10531 glTexStorage2DEXT(target, levels, internal_format, width, height); 10532 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); 10533 if (error == GL_NO_ERROR) { 10534 GLsizei level_width = width; 10535 GLsizei level_height = height; 10536 for (int ii = 0; ii < levels; ++ii) { 10537 texture_manager()->SetLevelInfo( 10538 texture_ref, target, ii, format, 10539 level_width, level_height, 1, 0, format, type, false); 10540 level_width = std::max(1, level_width >> 1); 10541 level_height = std::max(1, level_height >> 1); 10542 } 10543 texture->SetImmutable(true); 10544 } 10545 } 10546 10547 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( 10548 uint32 immediate_data_size, 10549 const void* cmd_data) { 10550 return error::kUnknownCommand; 10551 } 10552 10553 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, 10554 const GLbyte* data) { 10555 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM", 10556 "context", logger_.GetLogPrefix(), 10557 "mailbox[0]", static_cast<unsigned char>(data[0])); 10558 10559 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 10560 &state_, target); 10561 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data); 10562 } 10563 10564 void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id, 10565 GLenum target, const GLbyte* data) { 10566 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM", 10567 "context", logger_.GetLogPrefix(), 10568 "mailbox[0]", static_cast<unsigned char>(data[0])); 10569 10570 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id), 10571 target, data); 10572 } 10573 10574 void GLES2DecoderImpl::ProduceTextureRef(std::string func_name, 10575 TextureRef* texture_ref, GLenum target, const GLbyte* data) { 10576 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data); 10577 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a " 10578 "mailbox that was not generated by " 10579 "GenMailboxCHROMIUM."; 10580 10581 if (!texture_ref) { 10582 LOCAL_SET_GL_ERROR( 10583 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target"); 10584 return; 10585 } 10586 10587 Texture* produced = texture_manager()->Produce(texture_ref); 10588 if (!produced) { 10589 LOCAL_SET_GL_ERROR( 10590 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture"); 10591 return; 10592 } 10593 10594 if (produced->target() != target) { 10595 LOCAL_SET_GL_ERROR( 10596 GL_INVALID_OPERATION, func_name.c_str(), "invalid target"); 10597 return; 10598 } 10599 10600 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced); 10601 } 10602 10603 void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, 10604 const GLbyte* data) { 10605 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM", 10606 "context", logger_.GetLogPrefix(), 10607 "mailbox[0]", static_cast<unsigned char>(data[0])); 10608 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data); 10609 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a " 10610 "mailbox that was not generated by " 10611 "GenMailboxCHROMIUM."; 10612 10613 scoped_refptr<TextureRef> texture_ref = 10614 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); 10615 if (!texture_ref.get()) { 10616 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10617 "glConsumeTextureCHROMIUM", 10618 "unknown texture for target"); 10619 return; 10620 } 10621 GLuint client_id = texture_ref->client_id(); 10622 if (!client_id) { 10623 LOCAL_SET_GL_ERROR( 10624 GL_INVALID_OPERATION, 10625 "glConsumeTextureCHROMIUM", "unknown texture for target"); 10626 return; 10627 } 10628 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox); 10629 if (!texture) { 10630 LOCAL_SET_GL_ERROR( 10631 GL_INVALID_OPERATION, 10632 "glConsumeTextureCHROMIUM", "invalid mailbox name"); 10633 return; 10634 } 10635 if (texture->target() != target) { 10636 LOCAL_SET_GL_ERROR( 10637 GL_INVALID_OPERATION, 10638 "glConsumeTextureCHROMIUM", "invalid target"); 10639 return; 10640 } 10641 10642 DeleteTexturesHelper(1, &client_id); 10643 texture_ref = texture_manager()->Consume(client_id, texture); 10644 glBindTexture(target, texture_ref->service_id()); 10645 10646 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 10647 unit.bind_target = target; 10648 switch (target) { 10649 case GL_TEXTURE_2D: 10650 unit.bound_texture_2d = texture_ref; 10651 break; 10652 case GL_TEXTURE_CUBE_MAP: 10653 unit.bound_texture_cube_map = texture_ref; 10654 break; 10655 case GL_TEXTURE_EXTERNAL_OES: 10656 unit.bound_texture_external_oes = texture_ref; 10657 break; 10658 case GL_TEXTURE_RECTANGLE_ARB: 10659 unit.bound_texture_rectangle_arb = texture_ref; 10660 break; 10661 default: 10662 NOTREACHED(); // Validation should prevent us getting here. 10663 break; 10664 } 10665 } 10666 10667 error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate( 10668 uint32_t immediate_data_size, 10669 const void* cmd_data) { 10670 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c = 10671 *static_cast< 10672 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>( 10673 cmd_data); 10674 GLenum target = static_cast<GLenum>(c.target); 10675 uint32_t data_size; 10676 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) { 10677 return error::kOutOfBounds; 10678 } 10679 if (data_size > immediate_data_size) { 10680 return error::kOutOfBounds; 10681 } 10682 const GLbyte* mailbox = 10683 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size); 10684 if (!validators_->texture_bind_target.IsValid(target)) { 10685 LOCAL_SET_GL_ERROR_INVALID_ENUM( 10686 "glCreateAndConsumeTextureCHROMIUM", target, "target"); 10687 return error::kNoError; 10688 } 10689 if (mailbox == NULL) { 10690 return error::kOutOfBounds; 10691 } 10692 uint32_t client_id = c.client_id; 10693 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id); 10694 return error::kNoError; 10695 } 10696 10697 void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target, 10698 const GLbyte* data, GLuint client_id) { 10699 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM", 10700 "context", logger_.GetLogPrefix(), 10701 "mailbox[0]", static_cast<unsigned char>(data[0])); 10702 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data); 10703 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was " 10704 "passed a mailbox that was not " 10705 "generated by GenMailboxCHROMIUM."; 10706 10707 TextureRef* texture_ref = GetTexture(client_id); 10708 if (texture_ref) { 10709 LOCAL_SET_GL_ERROR( 10710 GL_INVALID_OPERATION, 10711 "glCreateAndConsumeTextureCHROMIUM", "client id already in use"); 10712 return; 10713 } 10714 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox); 10715 if (!texture) { 10716 LOCAL_SET_GL_ERROR( 10717 GL_INVALID_OPERATION, 10718 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name"); 10719 return; 10720 } 10721 if (texture->target() != target) { 10722 LOCAL_SET_GL_ERROR( 10723 GL_INVALID_OPERATION, 10724 "glCreateAndConsumeTextureCHROMIUM", "invalid target"); 10725 return; 10726 } 10727 10728 IdAllocatorInterface* id_allocator = 10729 group_->GetIdAllocator(id_namespaces::kTextures); 10730 id_allocator->MarkAsUsed(client_id); 10731 10732 texture_ref = texture_manager()->Consume(client_id, texture); 10733 } 10734 10735 void GLES2DecoderImpl::DoInsertEventMarkerEXT( 10736 GLsizei length, const GLchar* marker) { 10737 if (!marker) { 10738 marker = ""; 10739 } 10740 debug_marker_manager_.SetMarker( 10741 length ? std::string(marker, length) : std::string(marker)); 10742 } 10743 10744 void GLES2DecoderImpl::DoPushGroupMarkerEXT( 10745 GLsizei length, const GLchar* marker) { 10746 if (!marker) { 10747 marker = ""; 10748 } 10749 std::string name = length ? std::string(marker, length) : std::string(marker); 10750 debug_marker_manager_.PushGroup(name); 10751 gpu_tracer_->Begin(name, kTraceGroupMarker); 10752 } 10753 10754 void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) { 10755 debug_marker_manager_.PopGroup(); 10756 gpu_tracer_->End(kTraceGroupMarker); 10757 } 10758 10759 void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( 10760 GLenum target, GLint image_id) { 10761 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); 10762 10763 if (target == GL_TEXTURE_CUBE_MAP) { 10764 LOCAL_SET_GL_ERROR( 10765 GL_INVALID_ENUM, 10766 "glBindTexImage2DCHROMIUM", "invalid target"); 10767 return; 10768 } 10769 10770 // Default target might be conceptually valid, but disallow it to avoid 10771 // accidents. 10772 TextureRef* texture_ref = 10773 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); 10774 if (!texture_ref) { 10775 LOCAL_SET_GL_ERROR( 10776 GL_INVALID_OPERATION, 10777 "glBindTexImage2DCHROMIUM", "no texture bound"); 10778 return; 10779 } 10780 10781 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 10782 if (!gl_image) { 10783 LOCAL_SET_GL_ERROR( 10784 GL_INVALID_OPERATION, 10785 "glBindTexImage2DCHROMIUM", "no image found with the given ID"); 10786 return; 10787 } 10788 10789 { 10790 ScopedGLErrorSuppressor suppressor( 10791 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState()); 10792 if (!gl_image->BindTexImage(target)) { 10793 LOCAL_SET_GL_ERROR( 10794 GL_INVALID_OPERATION, 10795 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID"); 10796 return; 10797 } 10798 } 10799 10800 gfx::Size size = gl_image->GetSize(); 10801 texture_manager()->SetLevelInfo( 10802 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0, 10803 GL_RGBA, GL_UNSIGNED_BYTE, true); 10804 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image); 10805 } 10806 10807 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( 10808 GLenum target, GLint image_id) { 10809 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); 10810 10811 // Default target might be conceptually valid, but disallow it to avoid 10812 // accidents. 10813 TextureRef* texture_ref = 10814 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); 10815 if (!texture_ref) { 10816 LOCAL_SET_GL_ERROR( 10817 GL_INVALID_OPERATION, 10818 "glReleaseTexImage2DCHROMIUM", "no texture bound"); 10819 return; 10820 } 10821 10822 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 10823 if (!gl_image) { 10824 LOCAL_SET_GL_ERROR( 10825 GL_INVALID_OPERATION, 10826 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID"); 10827 return; 10828 } 10829 10830 // Do nothing when image is not currently bound. 10831 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image) 10832 return; 10833 10834 { 10835 ScopedGLErrorSuppressor suppressor( 10836 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState()); 10837 gl_image->ReleaseTexImage(target); 10838 } 10839 10840 texture_manager()->SetLevelInfo( 10841 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0, 10842 GL_RGBA, GL_UNSIGNED_BYTE, false); 10843 } 10844 10845 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( 10846 uint32 immediate_data_size, 10847 const void* cmd_data) { 10848 const gles2::cmds::TraceBeginCHROMIUM& c = 10849 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data); 10850 Bucket* bucket = GetBucket(c.bucket_id); 10851 if (!bucket || bucket->size() == 0) { 10852 return error::kInvalidArguments; 10853 } 10854 std::string command_name; 10855 if (!bucket->GetAsString(&command_name)) { 10856 return error::kInvalidArguments; 10857 } 10858 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this); 10859 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) { 10860 LOCAL_SET_GL_ERROR( 10861 GL_INVALID_OPERATION, 10862 "glTraceBeginCHROMIUM", "unable to create begin trace"); 10863 return error::kNoError; 10864 } 10865 return error::kNoError; 10866 } 10867 10868 void GLES2DecoderImpl::DoTraceEndCHROMIUM() { 10869 if (gpu_tracer_->CurrentName().empty()) { 10870 LOCAL_SET_GL_ERROR( 10871 GL_INVALID_OPERATION, 10872 "glTraceEndCHROMIUM", "no trace begin found"); 10873 return; 10874 } 10875 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this); 10876 gpu_tracer_->End(kTraceCHROMIUM); 10877 } 10878 10879 void GLES2DecoderImpl::DoDrawBuffersEXT( 10880 GLsizei count, const GLenum* bufs) { 10881 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) { 10882 LOCAL_SET_GL_ERROR( 10883 GL_INVALID_VALUE, 10884 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT"); 10885 return; 10886 } 10887 10888 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 10889 if (framebuffer) { 10890 for (GLsizei i = 0; i < count; ++i) { 10891 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) && 10892 bufs[i] != GL_NONE) { 10893 LOCAL_SET_GL_ERROR( 10894 GL_INVALID_OPERATION, 10895 "glDrawBuffersEXT", 10896 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT"); 10897 return; 10898 } 10899 } 10900 glDrawBuffersARB(count, bufs); 10901 framebuffer->SetDrawBuffers(count, bufs); 10902 } else { // backbuffer 10903 if (count > 1 || 10904 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) { 10905 LOCAL_SET_GL_ERROR( 10906 GL_INVALID_OPERATION, 10907 "glDrawBuffersEXT", 10908 "more than one buffer or bufs not GL_NONE or GL_BACK"); 10909 return; 10910 } 10911 GLenum mapped_buf = bufs[0]; 10912 if (GetBackbufferServiceId() != 0 && // emulated backbuffer 10913 bufs[0] == GL_BACK) { 10914 mapped_buf = GL_COLOR_ATTACHMENT0; 10915 } 10916 glDrawBuffersARB(count, &mapped_buf); 10917 group_->set_draw_buffer(bufs[0]); 10918 } 10919 } 10920 10921 void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) { 10922 group_->LoseContexts(other); 10923 reset_status_ = current; 10924 current_decoder_error_ = error::kLostContext; 10925 } 10926 10927 void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode, 10928 const GLfloat* matrix) { 10929 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM || 10930 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM); 10931 if (!features().chromium_path_rendering) { 10932 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10933 "glMatrixLoadfCHROMIUM", 10934 "function not available"); 10935 return; 10936 } 10937 10938 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM 10939 ? state_.projection_matrix 10940 : state_.modelview_matrix; 10941 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16); 10942 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV 10943 // since the values of the _NV and _CHROMIUM tokens match. 10944 glMatrixLoadfEXT(matrix_mode, matrix); 10945 } 10946 10947 void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) { 10948 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM || 10949 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM); 10950 10951 if (!features().chromium_path_rendering) { 10952 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10953 "glMatrixLoadIdentityCHROMIUM", 10954 "function not available"); 10955 return; 10956 } 10957 10958 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 10959 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10960 0.0f, 0.0f, 0.0f, 1.0f}; 10961 10962 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM 10963 ? state_.projection_matrix 10964 : state_.modelview_matrix; 10965 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix)); 10966 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV 10967 // since the values of the _NV and _CHROMIUM tokens match. 10968 glMatrixLoadIdentityEXT(matrix_mode); 10969 } 10970 10971 bool GLES2DecoderImpl::ValidateAsyncTransfer( 10972 const char* function_name, 10973 TextureRef* texture_ref, 10974 GLenum target, 10975 GLint level, 10976 const void * data) { 10977 // We only support async uploads to 2D textures for now. 10978 if (GL_TEXTURE_2D != target) { 10979 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target"); 10980 return false; 10981 } 10982 // We only support uploads to level zero for now. 10983 if (level != 0) { 10984 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0"); 10985 return false; 10986 } 10987 // A transfer buffer must be bound, even for asyncTexImage2D. 10988 if (data == NULL) { 10989 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0"); 10990 return false; 10991 } 10992 // We only support one async transfer in progress. 10993 if (!texture_ref || 10994 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 10995 LOCAL_SET_GL_ERROR( 10996 GL_INVALID_OPERATION, 10997 function_name, "transfer already in progress"); 10998 return false; 10999 } 11000 return true; 11001 } 11002 11003 base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure( 11004 uint32 async_upload_token, 11005 uint32 sync_data_shm_id, 11006 uint32 sync_data_shm_offset) { 11007 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id); 11008 if (!buffer.get() || 11009 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync))) 11010 return base::Closure(); 11011 11012 AsyncMemoryParams mem_params(buffer, 11013 sync_data_shm_offset, 11014 sizeof(AsyncUploadSync)); 11015 11016 scoped_refptr<AsyncUploadTokenCompletionObserver> observer( 11017 new AsyncUploadTokenCompletionObserver(async_upload_token)); 11018 11019 return base::Bind( 11020 &AsyncPixelTransferManager::AsyncNotifyCompletion, 11021 base::Unretained(GetAsyncPixelTransferManager()), 11022 mem_params, 11023 observer); 11024 } 11025 11026 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( 11027 uint32 immediate_data_size, 11028 const void* cmd_data) { 11029 const gles2::cmds::AsyncTexImage2DCHROMIUM& c = 11030 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data); 11031 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); 11032 GLenum target = static_cast<GLenum>(c.target); 11033 GLint level = static_cast<GLint>(c.level); 11034 GLenum internal_format = static_cast<GLenum>(c.internalformat); 11035 GLsizei width = static_cast<GLsizei>(c.width); 11036 GLsizei height = static_cast<GLsizei>(c.height); 11037 GLint border = static_cast<GLint>(c.border); 11038 GLenum format = static_cast<GLenum>(c.format); 11039 GLenum type = static_cast<GLenum>(c.type); 11040 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 11041 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 11042 uint32 pixels_size; 11043 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); 11044 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); 11045 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 11046 11047 base::ScopedClosureRunner scoped_completion_callback; 11048 if (async_upload_token) { 11049 base::Closure completion_closure = 11050 AsyncUploadTokenCompletionClosure(async_upload_token, 11051 sync_data_shm_id, 11052 sync_data_shm_offset); 11053 if (completion_closure.is_null()) 11054 return error::kInvalidArguments; 11055 11056 scoped_completion_callback.Reset(completion_closure); 11057 } 11058 11059 // TODO(epenner): Move this and copies of this memory validation 11060 // into ValidateTexImage2D step. 11061 if (!GLES2Util::ComputeImageDataSizes( 11062 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 11063 NULL)) { 11064 return error::kOutOfBounds; 11065 } 11066 const void* pixels = NULL; 11067 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 11068 pixels = GetSharedMemoryAs<const void*>( 11069 pixels_shm_id, pixels_shm_offset, pixels_size); 11070 if (!pixels) { 11071 return error::kOutOfBounds; 11072 } 11073 } 11074 11075 TextureManager::DoTextImage2DArguments args = { 11076 target, level, internal_format, width, height, border, format, type, 11077 pixels, pixels_size}; 11078 TextureRef* texture_ref; 11079 // All the normal glTexSubImage2D validation. 11080 if (!texture_manager()->ValidateTexImage2D( 11081 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) { 11082 return error::kNoError; 11083 } 11084 11085 // Extra async validation. 11086 Texture* texture = texture_ref->texture(); 11087 if (!ValidateAsyncTransfer( 11088 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels)) 11089 return error::kNoError; 11090 11091 // Don't allow async redefinition of a textures. 11092 if (texture->IsDefined()) { 11093 LOCAL_SET_GL_ERROR( 11094 GL_INVALID_OPERATION, 11095 "glAsyncTexImage2DCHROMIUM", "already defined"); 11096 return error::kNoError; 11097 } 11098 11099 if (!EnsureGPUMemoryAvailable(pixels_size)) { 11100 LOCAL_SET_GL_ERROR( 11101 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory"); 11102 return error::kNoError; 11103 } 11104 11105 // Setup the parameters. 11106 AsyncTexImage2DParams tex_params = { 11107 target, level, static_cast<GLenum>(internal_format), 11108 width, height, border, format, type}; 11109 AsyncMemoryParams mem_params( 11110 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size); 11111 11112 // Set up the async state if needed, and make the texture 11113 // immutable so the async state stays valid. The level info 11114 // is set up lazily when the transfer completes. 11115 AsyncPixelTransferDelegate* delegate = 11116 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref, 11117 tex_params); 11118 texture->SetImmutable(true); 11119 11120 delegate->AsyncTexImage2D( 11121 tex_params, 11122 mem_params, 11123 base::Bind(&TextureManager::SetLevelInfoFromParams, 11124 // The callback is only invoked if the transfer delegate still 11125 // exists, which implies through manager->texture_ref->state 11126 // ownership that both of these pointers are valid. 11127 base::Unretained(texture_manager()), 11128 base::Unretained(texture_ref), 11129 tex_params)); 11130 return error::kNoError; 11131 } 11132 11133 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( 11134 uint32 immediate_data_size, 11135 const void* cmd_data) { 11136 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c = 11137 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data); 11138 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); 11139 GLenum target = static_cast<GLenum>(c.target); 11140 GLint level = static_cast<GLint>(c.level); 11141 GLint xoffset = static_cast<GLint>(c.xoffset); 11142 GLint yoffset = static_cast<GLint>(c.yoffset); 11143 GLsizei width = static_cast<GLsizei>(c.width); 11144 GLsizei height = static_cast<GLsizei>(c.height); 11145 GLenum format = static_cast<GLenum>(c.format); 11146 GLenum type = static_cast<GLenum>(c.type); 11147 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); 11148 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); 11149 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 11150 11151 base::ScopedClosureRunner scoped_completion_callback; 11152 if (async_upload_token) { 11153 base::Closure completion_closure = 11154 AsyncUploadTokenCompletionClosure(async_upload_token, 11155 sync_data_shm_id, 11156 sync_data_shm_offset); 11157 if (completion_closure.is_null()) 11158 return error::kInvalidArguments; 11159 11160 scoped_completion_callback.Reset(completion_closure); 11161 } 11162 11163 // TODO(epenner): Move this and copies of this memory validation 11164 // into ValidateTexSubImage2D step. 11165 uint32 data_size; 11166 if (!GLES2Util::ComputeImageDataSizes( 11167 width, height, format, type, state_.unpack_alignment, &data_size, 11168 NULL, NULL)) { 11169 return error::kOutOfBounds; 11170 } 11171 const void* pixels = GetSharedMemoryAs<const void*>( 11172 c.data_shm_id, c.data_shm_offset, data_size); 11173 11174 // All the normal glTexSubImage2D validation. 11175 error::Error error = error::kNoError; 11176 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM", 11177 target, level, xoffset, yoffset, width, height, format, type, pixels)) { 11178 return error; 11179 } 11180 11181 // Extra async validation. 11182 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 11183 &state_, target); 11184 Texture* texture = texture_ref->texture(); 11185 if (!ValidateAsyncTransfer( 11186 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels)) 11187 return error::kNoError; 11188 11189 // Guarantee async textures are always 'cleared' as follows: 11190 // - AsyncTexImage2D can not redefine an existing texture 11191 // - AsyncTexImage2D must initialize the entire image via non-null buffer. 11192 // - AsyncTexSubImage2D clears synchronously if not already cleared. 11193 // - Textures become immutable after an async call. 11194 // This way we know in all cases that an async texture is always clear. 11195 if (!texture->SafeToRenderFrom()) { 11196 if (!texture_manager()->ClearTextureLevel(this, texture_ref, 11197 target, level)) { 11198 LOCAL_SET_GL_ERROR( 11199 GL_OUT_OF_MEMORY, 11200 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big"); 11201 return error::kNoError; 11202 } 11203 } 11204 11205 // Setup the parameters. 11206 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset, 11207 width, height, format, type}; 11208 AsyncMemoryParams mem_params( 11209 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size); 11210 AsyncPixelTransferDelegate* delegate = 11211 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref); 11212 if (!delegate) { 11213 // TODO(epenner): We may want to enforce exclusive use 11214 // of async APIs in which case this should become an error, 11215 // (the texture should have been async defined). 11216 AsyncTexImage2DParams define_params = {target, level, 11217 0, 0, 0, 0, 0, 0}; 11218 texture->GetLevelSize(target, level, &define_params.width, 11219 &define_params.height); 11220 texture->GetLevelType(target, level, &define_params.type, 11221 &define_params.internal_format); 11222 // Set up the async state if needed, and make the texture 11223 // immutable so the async state stays valid. 11224 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate( 11225 texture_ref, define_params); 11226 texture->SetImmutable(true); 11227 } 11228 11229 delegate->AsyncTexSubImage2D(tex_params, mem_params); 11230 return error::kNoError; 11231 } 11232 11233 error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM( 11234 uint32 immediate_data_size, 11235 const void* cmd_data) { 11236 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c = 11237 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data); 11238 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM"); 11239 GLenum target = static_cast<GLenum>(c.target); 11240 11241 if (GL_TEXTURE_2D != target) { 11242 LOCAL_SET_GL_ERROR( 11243 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target"); 11244 return error::kNoError; 11245 } 11246 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 11247 &state_, target); 11248 if (!texture_ref) { 11249 LOCAL_SET_GL_ERROR( 11250 GL_INVALID_OPERATION, 11251 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture"); 11252 return error::kNoError; 11253 } 11254 AsyncPixelTransferDelegate* delegate = 11255 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref); 11256 if (!delegate) { 11257 LOCAL_SET_GL_ERROR( 11258 GL_INVALID_OPERATION, 11259 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started"); 11260 return error::kNoError; 11261 } 11262 delegate->WaitForTransferCompletion(); 11263 ProcessFinishedAsyncTransfers(); 11264 return error::kNoError; 11265 } 11266 11267 error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM( 11268 uint32 immediate_data_size, 11269 const void* data) { 11270 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM"); 11271 11272 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D(); 11273 ProcessFinishedAsyncTransfers(); 11274 return error::kNoError; 11275 } 11276 11277 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( 11278 TextureRef* texture_ref) { 11279 Texture* texture = texture_ref->texture(); 11280 DoDidUseTexImageIfNeeded(texture, texture->target()); 11281 } 11282 11283 void GLES2DecoderImpl::OnOutOfMemoryError() { 11284 if (lose_context_when_out_of_memory_) { 11285 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); 11286 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB); 11287 } 11288 } 11289 11290 // Include the auto-generated part of this file. We split this because it means 11291 // we can easily edit the non-auto generated parts right here in this file 11292 // instead of having to edit some template or the code generator. 11293 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 11294 11295 } // namespace gles2 11296 } // namespace gpu 11297