| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
 | 
| ===================================================================
 | 
| --- gpu/command_buffer/service/gles2_cmd_decoder.cc	(revision 89013)
 | 
| +++ gpu/command_buffer/service/gles2_cmd_decoder.cc	(working copy)
 | 
| @@ -126,7 +126,7 @@
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| -static void WrappedTexImage2D(
 | 
| +void WrappedTexImage2D(
 | 
|      GLenum target,
 | 
|      GLint level,
 | 
|      GLenum internal_format,
 | 
| @@ -735,15 +735,6 @@
 | 
|    void RestoreCurrentRenderbufferBindings();
 | 
|    void RestoreCurrentTexture2DBindings();
 | 
|  
 | 
| -  // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
 | 
| -  void ApplyDirtyState();
 | 
| -
 | 
| -  // These check the state of the currently bound framebuffer or the
 | 
| -  // backbuffer if no framebuffer is bound.
 | 
| -  bool BoundFramebufferHasColorAttachmentWithAlpha();
 | 
| -  bool BoundFramebufferHasDepthAttachment();
 | 
| -  bool BoundFramebufferHasStencilAttachment();
 | 
| -
 | 
|   private:
 | 
|    friend class ScopedGLErrorSuppressor;
 | 
|    friend class ScopedResolvedFrameBufferBinder;
 | 
| @@ -833,7 +824,6 @@
 | 
|    // Get the format of the currently bound frame buffer (either FBO or regular
 | 
|    // back buffer)
 | 
|    GLenum GetBoundReadFrameBufferInternalFormat();
 | 
| -  GLenum GetBoundDrawFrameBufferInternalFormat();
 | 
|  
 | 
|    // Wrapper for CompressedTexImage2D commands.
 | 
|    error::Error DoCompressedTexImage2D(
 | 
| @@ -1269,8 +1259,8 @@
 | 
|    // Wrapper for glValidateProgram.
 | 
|    void DoValidateProgram(GLuint program_client_id);
 | 
|  
 | 
| -  void DoCopyTextureToParentTextureCHROMIUM(
 | 
| -      GLuint client_texture_id, GLuint parent_client_texture_id);
 | 
| +  void DoCopyTextureToParentTextureCHROMIUM(GLuint client_texture_id,
 | 
| +                                    GLuint parent_client_texture_id);
 | 
|  
 | 
|    void DoResizeCHROMIUM(GLuint width, GLuint height);
 | 
|  
 | 
| @@ -1472,7 +1462,6 @@
 | 
|    GLclampf clear_depth_;
 | 
|    GLboolean mask_depth_;
 | 
|    bool enable_scissor_test_;
 | 
| -  bool state_dirty_;
 | 
|  
 | 
|    // The program in use by glUseProgram
 | 
|    ProgramManager::ProgramInfo::Ref current_program_;
 | 
| @@ -1512,8 +1501,6 @@
 | 
|  
 | 
|    // The format of the back buffer_
 | 
|    GLenum back_buffer_color_format_;
 | 
| -  bool back_buffer_has_depth_;
 | 
| -  bool back_buffer_has_stencil_;
 | 
|  
 | 
|    bool teximage2d_faster_than_texsubimage2d_;
 | 
|    bool bufferdata_faster_than_buffersubdata_;
 | 
| @@ -1857,7 +1844,6 @@
 | 
|        clear_depth_(1.0f),
 | 
|        mask_depth_(true),
 | 
|        enable_scissor_test_(false),
 | 
| -      state_dirty_(true),
 | 
|        offscreen_target_color_format_(0),
 | 
|        offscreen_target_depth_format_(0),
 | 
|        offscreen_target_stencil_format_(0),
 | 
| @@ -1865,8 +1851,6 @@
 | 
|        copy_texture_to_parent_texture_fb_(0),
 | 
|        offscreen_saved_color_format_(0),
 | 
|        back_buffer_color_format_(0),
 | 
| -      back_buffer_has_depth_(false),
 | 
| -      back_buffer_has_stencil_(false),
 | 
|        teximage2d_faster_than_texsubimage2d_(true),
 | 
|        bufferdata_faster_than_buffersubdata_(true),
 | 
|        current_decoder_error_(error::kNoError),
 | 
| @@ -1946,6 +1930,10 @@
 | 
|  
 | 
|    vertex_attrib_manager_.Initialize(group_->max_vertex_attribs());
 | 
|  
 | 
| +  GLint v = 0;
 | 
| +  glGetIntegerv(GL_ALPHA_BITS, &v);
 | 
| +  back_buffer_color_format_ = v ? GL_RGBA : GL_RGB;
 | 
| +
 | 
|    if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
 | 
|      // We have to enable vertex array 0 on OpenGL or it won't render. Note that
 | 
|      // OpenGL ES 2.0 does not have this issue.
 | 
| @@ -1973,30 +1961,11 @@
 | 
|    glActiveTexture(GL_TEXTURE0);
 | 
|    CHECK_GL_ERROR();
 | 
|  
 | 
| -  ContextCreationAttribParser attrib_parser;
 | 
| -  if (!attrib_parser.Parse(attribs))
 | 
| -    return false;
 | 
| -
 | 
| -  // These are NOT if the back buffer has these proprorties. They are
 | 
| -  // if we want the command buffer to enforce them regardless of what
 | 
| -  // the real backbuffer is assuming the real back buffer gives us more than
 | 
| -  // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
 | 
| -  // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
 | 
| -  // can't do anything about that.
 | 
| -
 | 
| -  GLint v = 0;
 | 
| -  glGetIntegerv(GL_ALPHA_BITS, &v);
 | 
| -  // This checks if the user requested RGBA and we have RGBA then RGBA. If the
 | 
| -  // user requested RGB then RGB. If the user did not specify a preference than
 | 
| -  // use whatever we were given. Same for DEPTH and STENCIL.
 | 
| -  back_buffer_color_format_ =
 | 
| -      (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
 | 
| -  glGetIntegerv(GL_DEPTH_BITS, &v);
 | 
| -  back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
 | 
| -  glGetIntegerv(GL_STENCIL_BITS, &v);
 | 
| -  back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
 | 
| -
 | 
|    if (surface_->IsOffscreen()) {
 | 
| +    ContextCreationAttribParser attrib_parser;
 | 
| +    if (!attrib_parser.Parse(attribs))
 | 
| +      return false;
 | 
| +
 | 
|      if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
 | 
|          (context_->HasExtension("GL_EXT_framebuffer_multisample") ||
 | 
|           context_->HasExtension("GL_ANGLE_framebuffer_multisample"))) {
 | 
| @@ -2265,10 +2234,6 @@
 | 
|      FramebufferManager::FramebufferInfo* info =
 | 
|          GetFramebufferInfo(client_ids[ii]);
 | 
|      if (info) {
 | 
| -      if (info == bound_draw_framebuffer_) {
 | 
| -        bound_draw_framebuffer_ = NULL;
 | 
| -        state_dirty_ = true;
 | 
| -      }
 | 
|        GLuint service_id = info->service_id();
 | 
|        glDeleteFramebuffersEXT(1, &service_id);
 | 
|        RemoveFramebufferInfo(client_ids[ii]);
 | 
| @@ -2282,7 +2247,6 @@
 | 
|      RenderbufferManager::RenderbufferInfo* info =
 | 
|          GetRenderbufferInfo(client_ids[ii]);
 | 
|      if (info) {
 | 
| -      state_dirty_ = true;
 | 
|        GLuint service_id = info->service_id();
 | 
|        glDeleteRenderbuffersEXT(1, &service_id);
 | 
|        RemoveRenderbufferInfo(client_ids[ii]);
 | 
| @@ -2295,9 +2259,6 @@
 | 
|    for (GLsizei ii = 0; ii < n; ++ii) {
 | 
|      TextureManager::TextureInfo* info = GetTextureInfo(client_ids[ii]);
 | 
|      if (info) {
 | 
| -      if (info->IsAttachedToFramebuffer()) {
 | 
| -        state_dirty_ = true;
 | 
| -      }
 | 
|        GLuint service_id = info->service_id();
 | 
|        glDeleteTextures(1, &service_id);
 | 
|        RemoveTextureInfo(client_ids[ii]);
 | 
| @@ -2322,17 +2283,13 @@
 | 
|      FramebufferManager::FramebufferInfo* info,
 | 
|      FrameBuffer* offscreen_frame_buffer) {
 | 
|    GLuint framebuffer_id = info ? info->service_id() : 0;
 | 
| -
 | 
|    if (framebuffer_id == 0 && offscreen_frame_buffer) {
 | 
|      framebuffer_id = offscreen_frame_buffer->id();
 | 
|    }
 | 
| -
 | 
|    glBindFramebufferEXT(target, framebuffer_id);
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
 | 
| -  state_dirty_ = true;
 | 
| -
 | 
|    if (!feature_info_->feature_flags().chromium_framebuffer_multisample) {
 | 
|      RebindCurrentFramebuffer(
 | 
|          GL_FRAMEBUFFER,
 | 
| @@ -2389,7 +2346,12 @@
 | 
|  
 | 
|  GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
 | 
|    if (bound_read_framebuffer_ != 0) {
 | 
| -    return bound_read_framebuffer_->GetColorAttachmentFormat();
 | 
| +    const FramebufferManager::FramebufferInfo::Attachment* attachment =
 | 
| +        bound_read_framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
 | 
| +    if (attachment) {
 | 
| +      return attachment->internal_format();
 | 
| +    }
 | 
| +    return 0;
 | 
|    } else if (offscreen_target_frame_buffer_.get()) {
 | 
|      return offscreen_target_color_format_;
 | 
|    } else {
 | 
| @@ -2397,16 +2359,6 @@
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
 | 
| -  if (bound_draw_framebuffer_ != 0) {
 | 
| -    return bound_draw_framebuffer_->GetColorAttachmentFormat();
 | 
| -  } else if (offscreen_target_frame_buffer_.get()) {
 | 
| -    return offscreen_target_color_format_;
 | 
| -  } else {
 | 
| -    return back_buffer_color_format_;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
|  bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
 | 
|    if (offscreen_size_ == pending_offscreen_size_)
 | 
|      return true;
 | 
| @@ -2491,7 +2443,7 @@
 | 
|    // Clear the target frame buffer.
 | 
|    {
 | 
|      ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
 | 
| -    glClearColor(0, 0, 0, offscreen_target_color_format_ == GL_RGB);
 | 
| +    glClearColor(0, 0, 0, 0);
 | 
|      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 | 
|      glClearStencil(0);
 | 
|      glStencilMaskSeparate(GL_FRONT, GL_TRUE);
 | 
| @@ -2872,47 +2824,6 @@
 | 
|    glBindBuffer(target, service_id);
 | 
|  }
 | 
|  
 | 
| -bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
 | 
| -  return (GLES2Util::GetChannelsForFormat(
 | 
| -      GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
 | 
| -}
 | 
| -
 | 
| -bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
 | 
| -  if (bound_draw_framebuffer_) {
 | 
| -    return bound_draw_framebuffer_->HasDepthAttachment();
 | 
| -  }
 | 
| -  if (offscreen_target_frame_buffer_.get()) {
 | 
| -    return offscreen_target_depth_format_ != 0;
 | 
| -  }
 | 
| -  return back_buffer_has_depth_;
 | 
| -}
 | 
| -
 | 
| -bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
 | 
| -  if (bound_draw_framebuffer_) {
 | 
| -    return bound_draw_framebuffer_->HasStencilAttachment();
 | 
| -  }
 | 
| -  if (offscreen_target_frame_buffer_.get()) {
 | 
| -    return offscreen_target_stencil_format_ != 0;
 | 
| -  }
 | 
| -  return back_buffer_has_stencil_;
 | 
| -}
 | 
| -
 | 
| -void GLES2DecoderImpl::ApplyDirtyState() {
 | 
| -  if (state_dirty_) {
 | 
| -    glColorMask(
 | 
| -        mask_red_, mask_green_, mask_blue_,
 | 
| -        mask_alpha_ && BoundFramebufferHasColorAttachmentWithAlpha());
 | 
| -    glDepthMask(mask_depth_ && BoundFramebufferHasDepthAttachment());
 | 
| -    glStencilMaskSeparate(
 | 
| -       GL_FRONT,
 | 
| -       BoundFramebufferHasStencilAttachment() ? mask_stencil_front_ : 0);
 | 
| -    glStencilMaskSeparate(
 | 
| -       GL_BACK,
 | 
| -       BoundFramebufferHasStencilAttachment() ? mask_stencil_back_ : 0);
 | 
| -    state_dirty_ = false;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
|  void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
 | 
|    FramebufferManager::FramebufferInfo* info = NULL;
 | 
|    GLuint service_id = 0;
 | 
| @@ -2941,13 +2852,10 @@
 | 
|      bound_read_framebuffer_ = info;
 | 
|    }
 | 
|  
 | 
| -  state_dirty_ = true;
 | 
| -
 | 
|    // When rendering to an offscreen frame buffer, instead of unbinding from
 | 
|    // the current frame buffer, bind to the offscreen target frame buffer.
 | 
| -  if (info == NULL && offscreen_target_frame_buffer_.get()) {
 | 
| +  if (info == NULL && offscreen_target_frame_buffer_.get())
 | 
|      service_id = offscreen_target_frame_buffer_->id();
 | 
| -  }
 | 
|  
 | 
|    glBindFramebufferEXT(target, service_id);
 | 
|  }
 | 
| @@ -3101,57 +3009,6 @@
 | 
|      }
 | 
|    }
 | 
|    switch (pname) {
 | 
| -    case GL_COLOR_WRITEMASK:
 | 
| -      *num_written = 4;
 | 
| -      if (params) {
 | 
| -        params[0] = mask_red_;
 | 
| -        params[1] = mask_green_;
 | 
| -        params[2] = mask_blue_;
 | 
| -        params[3] = mask_alpha_;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_DEPTH_WRITEMASK:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        params[0] = mask_depth_;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_STENCIL_BACK_WRITEMASK:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        params[0] = mask_stencil_back_;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_STENCIL_WRITEMASK:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        params[0] = mask_stencil_front_;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_ALPHA_BITS:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        GLint v = 0;
 | 
| -        glGetIntegerv(GL_ALPHA_BITS, &v);
 | 
| -        params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_DEPTH_BITS:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        GLint v = 0;
 | 
| -        glGetIntegerv(GL_DEPTH_BITS, &v);
 | 
| -        params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
 | 
| -      }
 | 
| -      return true;
 | 
| -    case GL_STENCIL_BITS:
 | 
| -      *num_written = 1;
 | 
| -      if (params) {
 | 
| -        GLint v = 0;
 | 
| -        glGetIntegerv(GL_STENCIL_BITS, &v);
 | 
| -        params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
 | 
| -      }
 | 
| -      return true;
 | 
|      case GL_COMPRESSED_TEXTURE_FORMATS:
 | 
|        *num_written = 0;
 | 
|        // We don't support compressed textures.
 | 
| @@ -3543,7 +3400,6 @@
 | 
|  
 | 
|  void GLES2DecoderImpl::DoClear(GLbitfield mask) {
 | 
|    if (CheckFramebufferComplete("glClear")) {
 | 
| -    ApplyDirtyState();
 | 
|      glClear(mask);
 | 
|    }
 | 
|  }
 | 
| @@ -3570,7 +3426,6 @@
 | 
|      bool simulated_fixed_attribs = false;
 | 
|      if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
 | 
|        bool textures_set = SetBlackTextureForNonRenderableTextures();
 | 
| -      ApplyDirtyState();
 | 
|        glDrawArrays(mode, first, count);
 | 
|        if (textures_set) {
 | 
|          RestoreStateForNonRenderableTextures();
 | 
| @@ -3619,9 +3474,6 @@
 | 
|        }
 | 
|      }
 | 
|    }
 | 
| -  if (framebuffer_info == bound_draw_framebuffer_) {
 | 
| -    state_dirty_ = true;
 | 
| -  }
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
 | 
| @@ -3669,28 +3521,27 @@
 | 
|    mask_green_ = green;
 | 
|    mask_blue_ = blue;
 | 
|    mask_alpha_ = alpha;
 | 
| -  state_dirty_ = true;
 | 
| +  glColorMask(red, green, blue, alpha);
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::DoDepthMask(GLboolean depth) {
 | 
|    mask_depth_ = depth;
 | 
| -  state_dirty_ = true;
 | 
| +  glDepthMask(depth);
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::DoStencilMask(GLuint mask) {
 | 
|    mask_stencil_front_ = mask;
 | 
|    mask_stencil_back_ = mask;
 | 
| -  state_dirty_ = true;
 | 
| +  glStencilMask(mask);
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::DoStencilMaskSeparate(GLenum face, GLuint mask) {
 | 
| -  if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
 | 
| +  if (face == GL_FRONT) {
 | 
|      mask_stencil_front_ = mask;
 | 
| -  }
 | 
| -  if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
 | 
| +  } else {
 | 
|      mask_stencil_back_ = mask;
 | 
|    }
 | 
| -  state_dirty_ = true;
 | 
| +  glStencilMaskSeparate(face, mask);
 | 
|  }
 | 
|  
 | 
|  // NOTE: There's an assumption here that Texture attachments
 | 
| @@ -3735,10 +3586,13 @@
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::RestoreClearState() {
 | 
| -  state_dirty_ = true;
 | 
|    glClearColor(clear_red_, clear_green_, clear_blue_, clear_alpha_);
 | 
| +  glColorMask(mask_red_, mask_green_, mask_blue_, mask_alpha_);
 | 
|    glClearStencil(clear_stencil_);
 | 
| +  glStencilMaskSeparate(GL_FRONT, mask_stencil_front_);
 | 
| +  glStencilMaskSeparate(GL_BACK, mask_stencil_back_);
 | 
|    glClearDepth(clear_depth_);
 | 
| +  glDepthMask(mask_depth_);
 | 
|    if (enable_scissor_test_) {
 | 
|      glEnable(GL_SCISSOR_TEST);
 | 
|    }
 | 
| @@ -3784,9 +3638,6 @@
 | 
|        ClearUnclearedRenderbuffers(target, framebuffer_info);
 | 
|      }
 | 
|    }
 | 
| -  if (framebuffer_info == bound_draw_framebuffer_) {
 | 
| -    state_dirty_ = true;
 | 
| -  }
 | 
|  }
 | 
|  
 | 
|  void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
 | 
| @@ -4582,7 +4433,6 @@
 | 
|      bool simulated_fixed_attribs = false;
 | 
|      if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
 | 
|        bool textures_set = SetBlackTextureForNonRenderableTextures();
 | 
| -      ApplyDirtyState();
 | 
|        const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
 | 
|        glDrawElements(mode, count, type, indices);
 | 
|        if (textures_set) {
 | 
| @@ -5798,10 +5648,6 @@
 | 
|      pixels = zero.get();
 | 
|    }
 | 
|  
 | 
| -  if (info->IsAttachedToFramebuffer()) {
 | 
| -    state_dirty_ = true;
 | 
| -  }
 | 
| -
 | 
|    if (!teximage2d_faster_than_texsubimage2d_) {
 | 
|      GLsizei tex_width = 0;
 | 
|      GLsizei tex_height = 0;
 | 
| @@ -5982,10 +5828,6 @@
 | 
|    ScopedResolvedFrameBufferBinder binder(this, false);
 | 
|    gfx::Size size = GetBoundReadFrameBufferSize();
 | 
|  
 | 
| -  if (info->IsAttachedToFramebuffer()) {
 | 
| -    state_dirty_ = true;
 | 
| -  }
 | 
| -
 | 
|    // Clip to size to source dimensions
 | 
|    GLint copyX = 0;
 | 
|    GLint copyY = 0;
 | 
| 
 |