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