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