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