12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2010 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_renderer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <limits>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_layer_impl.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_metadata.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/output/copy_output_request.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/geometry_binding.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_frame_data.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/render_surface_filters.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/quads/picture_draw_quad.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/render_pass.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/stream_video_draw_quad.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/texture_draw_quad.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/layer_quad.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/scoped_resource.h"
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/resources/texture_mailbox_deleter.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "gpu/command_buffer/client/context_support.h"
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/common/gpu_memory_allocation.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/core/SkColorFilter.h"
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/skia/include/core/SkImage.h"
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkSurface.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/GrContext.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/GrTexture.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/SkGrTexturePixelRef.h"
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/geometry/quad_f.h"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/geometry/rect_conversions.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using gpu::gles2::GLES2Interface;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass FallbackFence : public ResourceProvider::Fence {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit FallbackFence(gpu::gles2::GLES2Interface* gl)
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : gl_(gl), has_passed_(true) {}
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Overridden from ResourceProvider::Fence:
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Set() OVERRIDE { has_passed_ = false; }
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual bool HasPassed() OVERRIDE {
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!has_passed_) {
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      has_passed_ = true;
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      Synchronize();
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return true;
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~FallbackFence() {}
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void Synchronize() {
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    TRACE_EVENT0("cc", "FallbackFence::Synchronize");
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->Finish();
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gpu::gles2::GLES2Interface* gl_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_passed_;
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FallbackFence);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NeedsIOSurfaceReadbackWorkaround() {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This isn't strictly required in DumpRenderTree-mode when Mesa is used,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // but it doesn't seem to hurt.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFloat4 UVTransform(const TextureDrawQuad* quad) {
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::PointF uv0 = quad->uv_top_left;
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::PointF uv1 = quad->uv_bottom_right;
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}};
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (quad->flipped) {
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    xform.data[1] = 1.0f - xform.data[1];
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    xform.data[3] = -xform.data[3];
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return xform;
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFloat4 PremultipliedColor(SkColor color) {
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const float factor = 1.0f / 255.0f;
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const float alpha = SkColorGetA(color) * factor;
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Float4 result = {
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      {SkColorGetR(color) * factor * alpha, SkColorGetG(color) * factor * alpha,
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       SkColorGetB(color) * factor * alpha, alpha}};
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return result;
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SamplerType SamplerTypeFromTextureTarget(GLenum target) {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (target) {
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_2D:
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2D;
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_RECTANGLE_ARB:
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2DRect;
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_EXTERNAL_OES:
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerTypeExternalOES;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NOTREACHED();
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2D;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Smallest unit that impact anti-aliasing output. We use this to
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// determine when anti-aliasing is unnecessary.
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Block or crash if the number of pending sync queries reach this high as
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// something is seriously wrong on the service side if this happens.
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const size_t kMaxPendingSyncQueries = 16;
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // anonymous namespace
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic GLint GetActiveTextureUnit(GLES2Interface* gl) {
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GLint active_unit = 0;
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return active_unit;
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass GLRenderer::ScopedUseGrContext {
1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public:
1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer,
1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                               DrawingFrame* frame) {
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!renderer->output_surface_->context_provider()->GrContext())
1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return scoped_ptr<ScopedUseGrContext>();
1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return make_scoped_ptr(new ScopedUseGrContext(renderer, frame));
1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ~ScopedUseGrContext() { PassControlToGLRenderer(); }
1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  GrContext* context() const {
1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return renderer_->output_surface_->context_provider()->GrContext();
1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private:
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedUseGrContext(GLRenderer* renderer, DrawingFrame* frame)
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      : renderer_(renderer), frame_(frame) {
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PassControlToSkia();
1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void PassControlToSkia() { context()->resetContext(); }
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void PassControlToGLRenderer() {
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    renderer_->RestoreGLState();
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    renderer_->RestoreFramebuffer(frame_);
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  GLRenderer* renderer_;
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DrawingFrame* frame_;
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DISALLOW_COPY_AND_ASSIGN(ScopedUseGrContext);
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct GLRenderer::PendingAsyncReadPixels {
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingAsyncReadPixels() : buffer(0) {}
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<CopyOutputRequest> copy_request;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::CancelableClosure finished_read_pixels_callback;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned buffer;
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels);
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass GLRenderer::SyncQuery {
1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit SyncQuery(gpu::gles2::GLES2Interface* gl)
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : gl_(gl), query_id_(0u), is_pending_(false), weak_ptr_factory_(this) {
1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->GenQueriesEXT(1, &query_id_);
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~SyncQuery() { gl_->DeleteQueriesEXT(1, &query_id_); }
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ResourceProvider::Fence> Begin() {
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK(!IsPending());
1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Invalidate weak pointer held by old fence.
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    weak_ptr_factory_.InvalidateWeakPtrs();
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Note: In case the set of drawing commands issued before End() do not
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // depend on the query, defer BeginQueryEXT call until Set() is called and
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // query is required.
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return make_scoped_refptr<ResourceProvider::Fence>(
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        new Fence(weak_ptr_factory_.GetWeakPtr()));
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void Set() {
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (is_pending_)
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Note: BeginQueryEXT on GL_COMMANDS_COMPLETED_CHROMIUM is effectively a
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // noop relative to GL, so it doesn't matter where it happens but we still
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // make sure to issue this command when Set() is called (prior to issuing
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // any drawing commands that depend on query), in case some future extension
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // can take advantage of this.
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query_id_);
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    is_pending_ = true;
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void End() {
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!is_pending_)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool IsPending() {
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!is_pending_)
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    unsigned result_available = 1;
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->GetQueryObjectuivEXT(
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &result_available);
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    is_pending_ = !result_available;
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return is_pending_;
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Wait() {
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!is_pending_)
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unsigned result = 0;
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &result);
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    is_pending_ = false;
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  class Fence : public ResourceProvider::Fence {
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch   public:
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    explicit Fence(base::WeakPtr<GLRenderer::SyncQuery> query)
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        : query_(query) {}
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Overridden from ResourceProvider::Fence:
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    virtual void Set() OVERRIDE {
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK(query_);
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      query_->Set();
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual bool HasPassed() OVERRIDE {
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return !query_ || !query_->IsPending();
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch   private:
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual ~Fence() {}
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::WeakPtr<SyncQuery> query_;
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Fence);
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gpu::gles2::GLES2Interface* gl_;
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  unsigned query_id_;
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool is_pending_;
2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::WeakPtrFactory<SyncQuery> weak_ptr_factory_;
2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncQuery);
2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<GLRenderer> GLRenderer::Create(
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RendererClient* client,
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const LayerTreeSettings* settings,
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OutputSurface* output_surface,
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ResourceProvider* resource_provider,
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TextureMailboxDeleter* texture_mailbox_deleter,
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int highp_threshold_min) {
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return make_scoped_ptr(new GLRenderer(client,
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        settings,
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        output_surface,
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        resource_provider,
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        texture_mailbox_deleter,
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        highp_threshold_min));
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::GLRenderer(RendererClient* client,
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       const LayerTreeSettings* settings,
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       OutputSurface* output_surface,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       ResourceProvider* resource_provider,
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       TextureMailboxDeleter* texture_mailbox_deleter,
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       int highp_threshold_min)
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : DirectRenderer(client, settings, output_surface, resource_provider),
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_framebuffer_id_(0),
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      shared_geometry_quad_(QuadVertexRect()),
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_(output_surface->context_provider()->ContextGL()),
3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      context_support_(output_surface->context_provider()->ContextSupport()),
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      texture_mailbox_deleter_(texture_mailbox_deleter),
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_backbuffer_discarded_(false),
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      is_scissor_enabled_(false),
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scissor_rect_needs_reset_(true),
308fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      stencil_shadow_(false),
309fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      blend_shadow_(false),
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      highp_threshold_min_(highp_threshold_min),
311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      highp_threshold_cache_(0),
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      use_sync_query_(false),
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      on_demand_tile_raster_resource_id_(0) {
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(gl_);
3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(context_support_);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ContextProvider::Capabilities context_caps =
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      output_surface_->context_provider()->ContextCapabilities();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_partial_swap =
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      settings_->partial_swap_enabled && context_caps.gpu.post_sub_buffer;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!context_caps.gpu.iosurface || context_caps.gpu.texture_rectangle);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.using_egl_image = context_caps.gpu.egl_image_external;
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.max_texture_size = resource_provider_->max_texture_size();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.best_texture_format = resource_provider_->best_texture_format();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The updater can access textures while the GLRenderer is using them.
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.allow_partial_texture_updates = true;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  capabilities_.using_map_image = context_caps.gpu.map_image;
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.using_discard_framebuffer =
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      context_caps.gpu.discard_framebuffer;
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.allow_rasterize_on_demand = true;
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  use_sync_query_ = context_caps.gpu.sync_query;
3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeSharedObjects();
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::~GLRenderer() {
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!pending_async_read_pixels_.empty()) {
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back();
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pending_read->finished_read_pixels_callback.Cancel();
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pending_async_read_pixels_.pop_back();
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
352effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.clear();
353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CleanupSharedObjects();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const RendererCapabilitiesImpl& GLRenderer::Capabilities() const {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return capabilities_;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::DebugGLCall(GLES2Interface* gl,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const char* command,
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const char* file,
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int line) {
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint error = gl->GetError();
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error != GL_NO_ERROR)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "GL command failed: File: " << file << "\n\tLine " << line
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << "\n\tcommand: " << command << ", error "
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << static_cast<int>(error) << "\n";
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid GLRenderer::DidChangeVisibility() {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnforceMemoryPolicy();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  context_support_->SetSurfaceVisible(visible());
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void GLRenderer::DiscardPixels(bool has_external_stencil_test,
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               bool draw_rect_covers_full_surface) {
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (has_external_stencil_test || !draw_rect_covers_full_surface ||
38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      !capabilities_.using_discard_framebuffer)
38468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool using_default_framebuffer =
38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      !current_framebuffer_lock_ &&
38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      output_surface_->capabilities().uses_default_gl_framebuffer;
38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  GLenum attachments[] = {static_cast<GLenum>(
38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      using_default_framebuffer ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0_EXT)};
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->DiscardFramebufferEXT(
39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      GL_FRAMEBUFFER, arraysize(attachments), attachments);
39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void GLRenderer::ClearFramebuffer(DrawingFrame* frame,
39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  bool has_external_stencil_test) {
396fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // It's unsafe to clear when we have a stencil test because glClear ignores
397fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // stencil.
39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (has_external_stencil_test) {
399fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    DCHECK(!frame->current_render_pass->has_transparent_background);
400fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    return;
401fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
402fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On DEBUG builds, opaque render passes are cleared to blue to easily see
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // regions that were not drawn on the screen.
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (frame->current_render_pass->has_transparent_background)
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 0, 0));
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool always_clear = false;
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  always_clear = true;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (always_clear || frame->current_render_pass->has_transparent_background) {
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GLbitfield clear_bits = GL_COLOR_BUFFER_BIT;
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (always_clear)
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      clear_bits |= GL_STENCIL_BUFFER_BIT;
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->Clear(clear_bits);
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static ResourceProvider::ResourceId WaitOnResourceSyncPoints(
42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ResourceProvider* resource_provider,
42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ResourceProvider::ResourceId resource_id) {
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  resource_provider->WaitSyncPointIfNeeded(resource_id);
42603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return resource_id;
42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
42803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (frame->device_viewport_rect.IsEmpty())
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::BeginDrawingFrame");
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ResourceProvider::Fence> read_lock_fence;
4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (use_sync_query_) {
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Block until oldest sync query has passed if the number of pending queries
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // ever reach kMaxPendingSyncQueries.
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pending_sync_queries_.size() >= kMaxPendingSyncQueries) {
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      LOG(ERROR) << "Reached limit of pending sync queries.";
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pending_sync_queries_.front()->Wait();
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      DCHECK(!pending_sync_queries_.front()->IsPending());
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    while (!pending_sync_queries_.empty()) {
4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (pending_sync_queries_.front()->IsPending())
4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        break;
4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      available_sync_queries_.push_back(pending_sync_queries_.take_front());
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    current_sync_query_ = available_sync_queries_.empty()
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              ? make_scoped_ptr(new SyncQuery(gl_))
4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              : available_sync_queries_.take_front();
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    read_lock_fence = current_sync_query_->Begin();
4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    read_lock_fence = make_scoped_refptr(new FallbackFence(gl_));
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  resource_provider_->SetReadLockFence(read_lock_fence.get());
4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Insert WaitSyncPointCHROMIUM on quad resources prior to drawing the frame,
46403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // so that drawing can proceed without GL context switching interruptions.
46503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DrawQuad::ResourceIteratorCallback wait_on_resource_syncpoints_callback =
46603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&WaitOnResourceSyncPoints, resource_provider_);
46703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
46803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < frame->render_passes_in_draw_order->size(); ++i) {
46903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    RenderPass* pass = frame->render_passes_in_draw_order->at(i);
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (QuadList::Iterator iter = pass->quad_list.begin();
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         iter != pass->quad_list.end();
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         ++iter) {
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      iter->IterateResources(wait_on_resource_syncpoints_callback);
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
47503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
47603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(enne): Do we need to reinitialize all of this state per frame?
47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ReinitializeGLState();
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::DoNoOp() {
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Flush());
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(quad->rect.Contains(quad->visible_rect));
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->material != DrawQuad::TEXTURE_CONTENT) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FlushTextureQuadCache();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (quad->material) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::INVALID:
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::CHECKERBOARD:
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::DEBUG_BORDER:
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::IO_SURFACE_CONTENT:
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad));
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DrawQuad::PICTURE_CONTENT:
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad));
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::RENDER_PASS:
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::SOLID_COLOR:
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::STREAM_VIDEO_CONTENT:
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad));
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case DrawQuad::SURFACE_CONTENT:
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Surface content should be fully resolved to other quad types before
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // reaching a direct renderer.
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TEXTURE_CONTENT:
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EnqueueTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TILED_CONTENT:
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::YUV_VIDEO_CONTENT:
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawYUVVideoQuad(frame, YUVVideoDrawQuad::MaterialCast(quad));
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const CheckerboardDrawQuad* quad) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TileCheckerboardProgram* program = GetTileCheckerboardProgram();
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(program && (program->initialized() || IsContextLost()));
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkColor color = quad->color;
543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().color_location(),
545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetR(color) * (1.0f / 255.0f),
546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetG(color) * (1.0f / 255.0f),
547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetB(color) * (1.0f / 255.0f),
548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     1));
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int checkerboard_width = 16;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float frequency = 1.0f / checkerboard_width;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->rect;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_offset_x = tile_rect.x() % checkerboard_width;
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_offset_y = tile_rect.y() % checkerboard_width;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_x = tile_rect.width();
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_y = tile_rect.height();
558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().tex_transform_location(),
560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_offset_x,
561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_offset_y,
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_x,
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_y));
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform1f(program->fragment_shader().frequency_location(),
567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     frequency));
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(),
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->fragment_shader().alpha_location());
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(frame,
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->quadTransform(),
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->rect,
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->vertex_shader().matrix_location());
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const DebugBorderDrawQuad* quad) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const DebugBorderProgram* program = GetDebugBorderProgram();
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(program && (program->initialized() || IsContextLost()));
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use the full quad_rect for debug quads to not move the edges based on
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // partial swaps.
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect = quad->rect;
5890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gfx::Transform render_matrix;
5900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuadRectTransform(&render_matrix, quad->quadTransform(), layer_rect);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLRenderer::ToGLMatrix(&gl_matrix[0],
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         frame->projection_matrix * render_matrix);
593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          program->vertex_shader().matrix_location(), 1, false, &gl_matrix[0]));
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkColor color = quad->color;
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float alpha = SkColorGetA(color) * (1.0f / 255.0f);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().color_location(),
602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     alpha));
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->LineWidth(quad->width));
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The indices for the line are stored in the same array as the triangle
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // indices.
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0));
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic skia::RefPtr<SkImage> ApplyImageFilter(
6155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
6165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ResourceProvider* resource_provider,
6175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const gfx::Point& origin,
6186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const gfx::Vector2dF& scale,
6195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    SkImageFilter* filter,
6205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ScopedResource* source_texture_resource) {
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!filter)
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!use_gr_context)
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ResourceProvider::ScopedReadLockGL lock(resource_provider,
628c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          source_texture_resource->id());
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Wrap the source texture in a Ganesh platform texture.
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrBackendTextureDesc backend_texture_description;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fWidth = source_texture_resource->size().width();
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fHeight =
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_texture_resource->size().height();
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fTextureHandle = lock.texture_id();
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<GrTexture> texture =
6395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          backend_texture_description));
6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!texture) {
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_INSTANT0("cc",
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ApplyImageFilter wrap background texture failed",
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         TRACE_EVENT_SCOPE_THREAD);
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SkImageInfo info =
649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SkImageInfo::MakeN32Premul(source_texture_resource->size().width(),
650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 source_texture_resource->size().height());
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Place the platform texture inside an SkBitmap.
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap source;
65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  source.setInfo(info);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> pixel_ref =
655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(info, texture.get()));
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source.setPixelRef(pixel_ref.get());
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a scratch texture for backing store.
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrTextureDesc desc;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fSampleCnt = 0;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fWidth = source.width();
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fHeight = source.height();
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fConfig = kSkia8888_GrPixelConfig;
6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrAutoScratchTexture scratch_texture(
6675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      use_gr_context->context(), desc, GrContext::kExact_ScratchTexMatch);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<GrTexture> backing_store =
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      skia::AdoptRef(scratch_texture.detach());
6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!backing_store) {
67146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc",
67246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         "ApplyImageFilter scratch texture allocation failed",
67346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         TRACE_EVENT_SCOPE_THREAD);
6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
67546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create surface to draw into.
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkSurface> surface = skia::AdoptRef(
6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SkSurface::NewRenderTargetDirect(backing_store->asRenderTarget()));
6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw the source bitmap through the filter to the canvas.
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPaint paint;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setImageFilter(filter);
6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->clear(SK_ColorTRANSPARENT);
686424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->translate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y()));
6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->scale(scale.x(), scale.y());
6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->drawSprite(source, 0, 0, &paint);
6901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!image || !image->getTexture()) {
6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Flush the GrContext to ensure all buffered GL calls are drawn to the
6975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // backing store before we access and return it, and have cc begin using the
6985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // GL context again.
6991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->flush();
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return image;
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop(
7055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
7065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ResourceProvider* resource_provider,
7071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    skia::RefPtr<SkImage> source_bitmap_with_filters,
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedResource* source_texture_resource,
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedResource* background_texture_resource,
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkXfermode::Mode blend_mode) {
7115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!use_gr_context)
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return source_bitmap_with_filters;
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(background_texture_resource);
715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(source_texture_resource);
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Size source_size = source_texture_resource->size();
718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Size background_size = background_texture_resource->size();
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LE(background_size.width(), source_size.width());
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LE(background_size.height(), source_size.height());
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int source_texture_with_filters_id;
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (source_bitmap_with_filters) {
7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK_EQ(source_size.width(), source_bitmap_with_filters->width());
7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK_EQ(source_size.height(), source_bitmap_with_filters->height());
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GrTexture* texture =
7291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        reinterpret_cast<GrTexture*>(source_bitmap_with_filters->getTexture());
730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    source_texture_with_filters_id = texture->getTextureHandle();
731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    lock.reset(new ResourceProvider::ScopedReadLockGL(
7335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        resource_provider, source_texture_resource->id()));
734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    source_texture_with_filters_id = lock->texture_id();
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock_background(
7385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      resource_provider, background_texture_resource->id());
739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Wrap the source texture in a Ganesh platform texture.
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrBackendTextureDesc backend_texture_description;
742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fWidth = source_size.width();
746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fHeight = source_size.height();
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fTextureHandle = source_texture_with_filters_id;
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> source_texture =
7495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          backend_texture_description));
7511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!source_texture) {
7521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_INSTANT0(
7531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cc",
7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ApplyBlendModeWithBackdrop wrap source texture failed",
7551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TRACE_EVENT_SCOPE_THREAD);
7561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
7571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fWidth = background_size.width();
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fHeight = background_size.height();
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fTextureHandle = lock_background.texture_id();
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> background_texture =
7635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          backend_texture_description));
7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!background_texture) {
7661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_INSTANT0(
7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cc",
7681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ApplyBlendModeWithBackdrop wrap background texture failed",
7691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TRACE_EVENT_SCOPE_THREAD);
7701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SkImageInfo source_info =
774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SkImageInfo::MakeN32Premul(source_size.width(), source_size.height());
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Place the platform texture inside an SkBitmap.
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkBitmap source;
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  source.setInfo(source_info);
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> source_pixel_ref =
779a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(source_info, source_texture.get()));
780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  source.setPixelRef(source_pixel_ref.get());
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SkImageInfo background_info = SkImageInfo::MakeN32Premul(
783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      background_size.width(), background_size.height());
784a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkBitmap background;
78646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  background.setInfo(background_info);
787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> background_pixel_ref =
788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(
789a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          background_info, background_texture.get()));
790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  background.setPixelRef(background_pixel_ref.get());
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a scratch texture for backing store.
793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrTextureDesc desc;
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fSampleCnt = 0;
796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fWidth = source.width();
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fHeight = source.height();
798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fConfig = kSkia8888_GrPixelConfig;
799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrAutoScratchTexture scratch_texture(
8015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      use_gr_context->context(), desc, GrContext::kExact_ScratchTexMatch);
802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> backing_store =
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      skia::AdoptRef(scratch_texture.detach());
8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!backing_store) {
80546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    TRACE_EVENT_INSTANT0(
80646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cc",
80746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "ApplyBlendModeWithBackdrop scratch texture allocation failed",
80846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        TRACE_EVENT_SCOPE_THREAD);
80946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return source_bitmap_with_filters;
81046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a device and canvas using that backing store.
8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkSurface> surface = skia::AdoptRef(
8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SkSurface::NewRenderTargetDirect(backing_store->asRenderTarget()));
8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!surface)
8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Draw the source bitmap through the filter to the canvas.
8201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->clear(SK_ColorTRANSPARENT);
8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->drawSprite(background, 0, 0);
822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkPaint paint;
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  paint.setXfermodeMode(blend_mode);
8241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->drawSprite(source, 0, 0, &paint);
8251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
8271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!image || !image->getTexture()) {
8281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::RefPtr<SkImage>();
8291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Flush the GrContext to ensure all buffered GL calls are drawn to the
8325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // backing store before we access and return it, and have cc begin using the
8335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // GL context again.
8341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  canvas->flush();
835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return image;
837f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters(
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const RenderPassDrawQuad* quad,
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform& contents_device_transform,
843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const gfx::Transform& contents_device_transform_inverse,
844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool* background_changed) {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method draws a background filter, which applies a filter to any pixels
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // behind the quad and seen through its background.  The algorithm works as
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // follows:
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1. Compute a bounding box around the pixels that will be visible through
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the quad.
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2. Read the pixels in the bounding box into a buffer R.
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 3. Apply the background filter to R, so that it is applied in the pixels'
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // coordinate space.
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 4. Apply the quad's inverse transform to map the pixels in R into the
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad's content space. This implicitly clips R by the content bounds of the
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad since the destination texture has bounds matching the quad's content.
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 5. Draw the background texture for the contents using the same transform as
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to draw the contents itself. This is done without blending to replace
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the current background pixels with the new filtered background.
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 6. Draw the contents of the quad over drop of the new background with
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // blending, as per usual. The filtered background pixels will show through
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // any non-opaque pixels in this draws.
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): When this algorithm changes, update
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // LayerTreeHost::PrioritizeTextures() accordingly.
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): We only allow background filters on an opaque render surface
869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // because other surfaces may contain translucent pixels, and the contents
870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // behind those translucent pixels wouldn't have the filter applied.
871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool apply_background_filters =
872f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      !frame->current_render_pass->has_transparent_background;
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!frame->current_texture);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(ajuma): Add support for reference filters once
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // FilterOperations::GetOutsets supports reference filters.
877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (apply_background_filters && quad->background_filters.HasReferenceFilter())
878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    apply_background_filters = false;
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): Do a single readback for both the surface and replica and
881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // cache the filtered results (once filter textures are not reused).
8827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents_device_transform, SharedGeometryQuad().BoundingBox()));
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int top, right, bottom, left;
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  quad->background_filters.GetOutsets(&top, &right, &bottom, &left);
8877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  window_rect.Inset(-left, -top, -right, -bottom);
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  window_rect.Intersect(
8907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect));
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ScopedResource> device_background_texture =
893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ScopedResource::Create(resource_provider_);
89403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // CopyTexImage2D fails when called on a texture having immutable storage.
895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  device_background_texture->Allocate(
89603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      window_rect.size(), ResourceProvider::TextureHintDefault, RGBA_8888);
897a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
8987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
8997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                             device_background_texture->id());
900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(
901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        lock.texture_id(), device_background_texture->format(), window_rect);
9027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      quad->background_filters, device_background_texture->size());
9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkImage> filtered_device_background;
908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (apply_background_filters) {
909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background =
9105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        ApplyImageFilter(ScopedUseGrContext::Create(this, frame),
9115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         resource_provider_,
912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         quad->rect.origin(),
9136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                         quad->filters_scale,
914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         filter.get(),
915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         device_background_texture.get());
916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
9171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  *background_changed = (filtered_device_background != NULL);
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int filtered_device_background_texture_id = 0;
920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (filtered_device_background) {
9221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GrTexture* texture = filtered_device_background->getTexture();
923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background_texture_id = texture->getTextureHandle();
924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    lock.reset(new ResourceProvider::ScopedReadLockGL(
926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        resource_provider_, device_background_texture->id()));
927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background_texture_id = lock->texture_id();
928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ScopedResource> background_texture =
931a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ScopedResource::Create(resource_provider_);
932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  background_texture->Allocate(
93303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      quad->rect.size(),
93403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutableFramebuffer,
93503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      RGBA_8888);
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const RenderPass* target_render_pass = frame->current_render_pass;
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool using_background_texture =
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UseScopedTexture(frame, background_texture.get(), quad->rect);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (using_background_texture) {
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Copy the readback pixels from device to the background texture for the
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // surface.
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Transform device_to_framebuffer_transform;
9450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuadRectTransform(
9460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        &device_to_framebuffer_transform, gfx::Transform(), quad->rect);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_to_framebuffer_transform.PreconcatTransform(
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents_device_transform_inverse);
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->Clear(GL_COLOR_BUFFER_BIT);
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The filtered_deveice_background_texture is oriented the same as the frame
9567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // buffer. The transform we are copying with has a vertical flip, as well as
9577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the |device_to_framebuffer_transform|, which cancel each other out. So do
9587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // not flip the contents in the shader to maintain orientation.
9597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool flip_vertically = false;
9607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CopyTextureToFramebuffer(frame,
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             filtered_device_background_texture_id,
9637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             window_rect,
9647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             device_to_framebuffer_transform,
9657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             flip_vertically);
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UseRenderPass(frame, target_render_pass);
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!using_background_texture)
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ScopedResource>();
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return background_texture.Pass();
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const RenderPassDrawQuad* quad) {
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedResource* contents_texture =
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_pass_textures_.get(quad->render_pass_id);
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents_texture || !contents_texture->id())
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform =
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_device_transform.FlattenTo2d();
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Can only draw surface if device matrix is invertible.
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform_inverse(
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Transform::kSkipInitialization);
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents_device_transform.GetInverse(&contents_device_transform_inverse))
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool need_background_texture =
997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode ||
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      !quad->background_filters.IsEmpty();
999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool background_changed = false;
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ScopedResource> background_texture;
1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (need_background_texture) {
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The pixels from the filtered background should completely replace the
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // current pixel values.
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool disable_blending = blend_enabled();
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (disable_blending)
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetBlendEnabled(false);
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    background_texture =
1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        GetBackgroundWithFilters(frame,
1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 quad,
1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 contents_device_transform,
1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 contents_device_transform_inverse,
1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 &background_changed);
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (disable_blending)
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetBlendEnabled(true);
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(senorblanco): Cache this value so that we don't have to do it for both
1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the surface and its replica.  Apply filters to the contents texture.
10211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::RefPtr<SkImage> filter_bitmap;
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SkScalar color_matrix[20];
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_color_matrix = false;
10244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!quad->filters.IsEmpty()) {
102568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
102668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        quad->filters, contents_texture->size());
102768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (filter) {
102868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      skia::RefPtr<SkColorFilter> cf;
102968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
103068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      {
103168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        SkColorFilter* colorfilter_rawptr = NULL;
103268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        filter->asColorFilter(&colorfilter_rawptr);
103368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        cf = skia::AdoptRef(colorfilter_rawptr);
103468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
103568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
103668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (cf && cf->asColorMatrix(color_matrix) && !filter->getInput(0)) {
103768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // We have a single color matrix as a filter; apply it locally
103868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // in the compositor.
103968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        use_color_matrix = true;
104068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      } else {
10415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        filter_bitmap =
10425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            ApplyImageFilter(ScopedUseGrContext::Create(this, frame),
10435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             resource_provider_,
10445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             quad->rect.origin(),
10456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             quad->filters_scale,
10465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             filter.get(),
10475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             contents_texture);
104868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode &&
1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      background_texture) {
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filter_bitmap =
10555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame),
10565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   resource_provider_,
1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   filter_bitmap,
1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   contents_texture,
1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   background_texture.get(),
1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   quad->shared_quad_state->blend_mode);
1061f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Draw the background texture if it has some filters applied.
1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (background_texture && background_changed) {
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(background_texture->size() == quad->rect.size());
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(resource_provider_,
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            background_texture->id());
10687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
10697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The background_texture is oriented the same as the frame buffer. The
10707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // transform we are copying with has a vertical flip, so flip the contents
10717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // in the shader to maintain orientation
10727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool flip_vertically = true;
10737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
10747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    CopyTextureToFramebuffer(frame,
10757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             lock.texture_id(),
10767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             quad->rect,
10777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             quad->quadTransform(),
10787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             flip_vertically);
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool clipped = false;
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF device_quad = MathUtil::MapQuad(
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents_device_transform, SharedGeometryQuad(), &clipped);
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox()));
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_edges(device_quad);
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use anti-aliasing programs only when necessary.
1088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool use_aa =
1089a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      !clipped && (!device_quad.IsRectilinear() ||
1090a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
1091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                     kAntiAliasingEpsilon));
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_bounds.InflateAntiAliasingDistance();
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_edges.InflateAntiAliasingDistance();
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> mask_resource_lock;
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned mask_texture_id = 0;
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->mask_resource_id) {
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_resource_lock.reset(new ResourceProvider::ScopedReadLockGL(
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider_, quad->mask_resource_id));
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_texture_id = mask_resource_lock->texture_id();
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): use the background_texture and blend the background in with
1106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // this draw instead of having a separate copy of the background texture.
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
11091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (filter_bitmap) {
11101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GrTexture* texture = filter_bitmap->getTexture();
1111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
1112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
1114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    contents_resource_lock =
1115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        make_scoped_ptr(new ResourceProvider::ScopedSamplerGL(
1116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            resource_provider_, contents_texture->id(), GL_LINEAR));
1117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
1118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              contents_resource_lock->target());
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_quad_location = -1;
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_edge_location = -1;
1129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int shader_viewport_location = -1;
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_sampler_location = -1;
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_tex_coord_scale_location = -1;
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_tex_coord_offset_location = -1;
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_matrix_location = -1;
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_alpha_location = -1;
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int shader_color_matrix_location = -1;
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int shader_color_offset_location = -1;
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_tex_transform_location = -1;
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (use_aa && mask_texture_id && !use_color_matrix) {
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskProgramAA* program =
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskProgramAA(tex_coord_precision);
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
1146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_sampler_location =
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
11567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && mask_texture_id && !use_color_matrix) {
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskProgram* program =
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskProgram(tex_coord_precision);
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_sampler_location =
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_tex_transform_location =
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && !mask_texture_id && !use_color_matrix) {
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassProgramAA* program =
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassProgramAA(tex_coord_precision);
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
1181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
11857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && mask_texture_id && use_color_matrix) {
1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskColorMatrixProgramAA* program =
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision);
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
11957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_sampler_location =
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && !mask_texture_id && use_color_matrix) {
1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassColorMatrixProgramAA* program =
1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassColorMatrixProgramAA(tex_coord_precision);
1213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
12187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
12197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && mask_texture_id && use_color_matrix) {
1228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskColorMatrixProgram* program =
1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskColorMatrixProgram(tex_coord_precision);
1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_tex_transform_location =
1235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_sampler_location =
1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && !mask_texture_id && use_color_matrix) {
1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassColorMatrixProgram* program =
1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassColorMatrixProgram(tex_coord_precision);
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_tex_transform_location =
1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassProgram* program =
1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassProgram(tex_coord_precision);
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_tex_transform_location =
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_x =
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      quad->rect.width() / static_cast<float>(contents_texture->size().width());
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_y = quad->rect.height() /
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      static_cast<float>(contents_texture->size().height());
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(tex_scale_x, 1.0f);
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(tex_scale_y, 1.0f);
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(shader_tex_transform_location != -1 || IsContextLost());
12807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Flip the content vertically in the shader, as the RenderPass input
12817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // texture is already oriented the same way as the framebuffer, but the
12827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // projection transform does a flip.
1283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(shader_tex_transform_location,
1285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     0.0f,
1286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_y,
1287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_x,
1288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     -tex_scale_y));
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_mask_sampler_lock;
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shader_mask_sampler_location != -1) {
1292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE(shader_mask_tex_coord_scale_location, 1);
1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE(shader_mask_tex_coord_offset_location, 1);
1294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(shader_mask_sampler_location, 1));
12957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    float mask_tex_scale_x = quad->mask_uv_rect.width() / tex_scale_x;
12977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    float mask_tex_scale_y = quad->mask_uv_rect.height() / tex_scale_y;
12987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Mask textures are oriented vertically flipped relative to the framebuffer
13007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // and the RenderPass contents texture, so we flip the tex coords from the
13017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // RenderPass texture to find the mask texture coords.
1302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform2f(shader_mask_tex_coord_offset_location,
1304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->mask_uv_rect.x(),
1305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->mask_uv_rect.y() + quad->mask_uv_rect.height()));
1306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform2f(shader_mask_tex_coord_scale_location,
1308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       mask_tex_scale_x,
1309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       -mask_tex_scale_y));
1310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    shader_mask_sampler_lock = make_scoped_ptr(
1311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new ResourceProvider::ScopedSamplerGL(resource_provider_,
1312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              quad->mask_resource_id,
1313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              GL_TEXTURE1,
1314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              GL_LINEAR));
1315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
1316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              shader_mask_sampler_lock->target());
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shader_edge_location != -1) {
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float edge[24];
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_edges.ToFloatArray(edge);
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_bounds.ToFloatArray(&edge[12]);
1323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(shader_edge_location, 8, edge));
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (shader_viewport_location != -1) {
1327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(shader_viewport_location, 1, viewport));
1332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shader_color_matrix_location != -1) {
1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    float matrix[16];
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int i = 0; i < 4; ++i) {
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (int j = 0; j < 4; ++j)
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        matrix[i * 4 + j] = SkScalarToFloat(color_matrix[j * 5 + i]);
1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->UniformMatrix4fv(shader_color_matrix_location, 1, false, matrix));
1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const float kScale = 1.0f / 255.0f;
1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shader_color_offset_location != -1) {
1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    float offset[4];
1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int i = 0; i < 4; ++i)
1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      offset[i] = SkScalarToFloat(color_matrix[i * 5 + 4]) * kScale;
1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(shader_color_offset_location, 1, offset));
1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map device space quad to surface space. contents_device_transform has no 3d
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // component since it was flattened, so we don't need to project.
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse,
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              device_layer_edges.ToQuadF(),
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              &clipped);
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(), shader_alpha_location);
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderQuadF(surface_quad, shader_quad_location);
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), quad->rect, shader_matrix_location);
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush the compositor context before the filter bitmap goes out of
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // scope, so the draw gets processed before the filter texture gets deleted.
13651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (filter_bitmap)
1366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Flush());
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SolidColorProgramUniforms {
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program;
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned matrix_location;
1372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned viewport_location;
1373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned quad_location;
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned edge_location;
1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned color_location;
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class T>
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void SolidColorUniformLocation(T program,
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      SolidColorProgramUniforms* uniforms) {
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->program = program->program();
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->matrix_location = program->vertex_shader().matrix_location();
1383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->viewport_location = program->vertex_shader().viewport_location();
1384b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  uniforms->quad_location = program->vertex_shader().quad_location();
1385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->edge_location = program->vertex_shader().edge_location();
1386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->color_location = program->fragment_shader().color_location();
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::SetupQuadForAntialiasing(
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform& device_transform,
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DrawQuad* quad,
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::QuadF* local_quad,
139458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    float edge[24]) {
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool clipped = false;
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF device_layer_quad = MathUtil::MapQuad(
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_transform, gfx::QuadF(quad->visibleContentRect()), &clipped);
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_axis_aligned_in_target = device_layer_quad.IsRectilinear();
1402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool is_nearest_rect_within_epsilon =
1403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      is_axis_aligned_in_target &&
1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(),
1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       kAntiAliasingEpsilon);
140658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // AAing clipped quads is not supported by the code yet.
140758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool use_aa = !clipped && !is_nearest_rect_within_epsilon && quad->IsEdge();
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!use_aa)
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_bounds(gfx::QuadF(device_layer_quad.BoundingBox()));
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_bounds.InflateAntiAliasingDistance();
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_edges(device_layer_quad);
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_edges.InflateAntiAliasingDistance();
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_edges.ToFloatArray(edge);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_bounds.ToFloatArray(&edge[12]);
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF bottom_right = tile_rect.bottom_right();
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF bottom_left = tile_rect.bottom_left();
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF top_left = tile_rect.origin();
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF top_right = tile_rect.top_right();
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map points to device space.
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_right = MathUtil::MapPoint(device_transform, bottom_right, &clipped);
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_left = MathUtil::MapPoint(device_transform, bottom_left, &clipped);
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_left = MathUtil::MapPoint(device_transform, top_left, &clipped);
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_right = MathUtil::MapPoint(device_transform, top_right, &clipped);
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge bottom_edge(bottom_right, bottom_left);
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge left_edge(bottom_left, top_left);
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge top_edge(top_left, top_right);
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge right_edge(top_right, bottom_right);
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only apply anti-aliasing to edges not clipped by culling or scissoring.
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsTopEdge() && tile_rect.y() == quad->rect.y())
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    top_edge = device_layer_edges.top();
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsLeftEdge() && tile_rect.x() == quad->rect.x())
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    left_edge = device_layer_edges.left();
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsRightEdge() && tile_rect.right() == quad->rect.right())
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    right_edge = device_layer_edges.right();
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsBottomEdge() && tile_rect.bottom() == quad->rect.bottom())
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bottom_edge = device_layer_edges.bottom();
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float sign = gfx::QuadF(tile_rect).IsCounterClockwise() ? -1 : 1;
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_edge.scale(sign);
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  left_edge.scale(sign);
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_edge.scale(sign);
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  right_edge.scale(sign);
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create device space quad.
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_quad(left_edge, top_edge, right_edge, bottom_edge);
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map device space quad to local space. device_transform has no 3d
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // component since it was flattened, so we don't need to project.  We should
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have already checked that the transform was uninvertible above.
1462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool did_invert = device_transform.GetInverse(&inverse_device_transform);
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(did_invert);
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *local_quad = MathUtil::MapQuad(
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inverse_device_transform, device_quad.ToQuadF(), &clipped);
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not DCHECK(!clipped) here, because anti-aliasing inflation may
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // cause device_quad to become clipped. To our knowledge this scenario does
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not need to be handled differently than the unclipped case.
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const SolidColorDrawQuad* quad) {
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SkColor color = quad->color;
1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  float opacity = quad->opacity();
1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Early out if alpha is small enough that quad doesn't contribute to output.
1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (alpha < std::numeric_limits<float>::epsilon() &&
1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->ShouldDrawWithBlending())
1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform device_transform =
1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_transform.FlattenTo2d();
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_transform.IsInvertible())
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float edge[24];
149558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool use_aa =
149658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_->allow_antialiasing && !quad->force_anti_aliasing_off &&
149758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SolidColorProgramUniforms uniforms;
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa)
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SolidColorUniformLocation(GetSolidColorProgramAA(), &uniforms);
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SolidColorUniformLocation(GetSolidColorProgram(), &uniforms);
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(uniforms.program);
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(uniforms.color_location,
1508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
1509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
1510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
1511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     alpha));
1512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (use_aa) {
1513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
1518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
1519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable blending when the quad properties require it or if we decided
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to use antialiasing.
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normalize to tile_rect.
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetShaderQuadF(local_quad, uniforms.quad_location);
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transform and vertex data are used to figure out the extents that the
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // un-antialiased quad should have and which vertex this is and the float
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad passed in via uniform is the actual geometry that gets used to draw
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it. This is why this centered rect is used and not the original quad_rect.
1534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::RectF centered_rect(
1535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
1536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_rect.size());
1537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DrawQuadGeometry(
1538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TileProgramUniforms {
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program;
1543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned matrix_location;
1544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned viewport_location;
1545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned quad_location;
1546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned edge_location;
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned vertex_tex_transform_location;
1548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned sampler_location;
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned fragment_tex_transform_location;
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned alpha_location;
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T>
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void TileUniformLocation(T program, TileProgramUniforms* uniforms) {
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->program = program->program();
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->matrix_location = program->vertex_shader().matrix_location();
1557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->viewport_location = program->vertex_shader().viewport_location();
1558b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  uniforms->quad_location = program->vertex_shader().quad_location();
1559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->edge_location = program->vertex_shader().edge_location();
1560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->vertex_tex_transform_location =
1561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      program->vertex_shader().vertex_tex_transform_location();
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->sampler_location = program->fragment_shader().sampler_location();
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->alpha_location = program->fragment_shader().alpha_location();
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->fragment_tex_transform_location =
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program->fragment_shader().fragment_tex_transform_location();
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawTileQuad(const DrawingFrame* frame,
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const TileDrawQuad* quad) {
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawContentQuad(frame, quad, quad->resource_id);
1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawContentQuad(const DrawingFrame* frame,
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const ContentDrawQuadBase* quad,
1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 ResourceProvider::ResourceId resource_id) {
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional(
1580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      quad->tex_coord_rect, quad->rect, tile_rect);
1581424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  float tex_to_geom_scale_x = quad->rect.width() / quad->tex_coord_rect.width();
1582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  float tex_to_geom_scale_y =
1583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      quad->rect.height() / quad->tex_coord_rect.height();
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF clamp_geom_rect(tile_rect);
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF clamp_tex_rect(tex_coord_rect);
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clamp texture coordinates to avoid sampling outside the layer
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by deflating the tile region half a texel or half a texel
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // minus epsilon for one pixel layers. The resulting clamp region
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is mapped to the unit square by the vertex shader and mapped
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // back to normalized texture coordinates by the fragment shader
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after being clamped to 0-1 range.
1593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float tex_clamp_x =
1594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(0.5f, 0.5f * clamp_tex_rect.width() - kAntiAliasingEpsilon);
1595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float tex_clamp_y =
1596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(0.5f, 0.5f * clamp_tex_rect.height() - kAntiAliasingEpsilon);
1597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float geom_clamp_x =
1598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(tex_clamp_x * tex_to_geom_scale_x,
1599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               0.5f * clamp_geom_rect.width() - kAntiAliasingEpsilon);
1600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float geom_clamp_y =
1601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(tex_clamp_y * tex_to_geom_scale_y,
1602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               0.5f * clamp_geom_rect.height() - kAntiAliasingEpsilon);
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  clamp_geom_rect.Inset(geom_clamp_x, geom_clamp_y, geom_clamp_x, geom_clamp_y);
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  clamp_tex_rect.Inset(tex_clamp_x, tex_clamp_y, tex_clamp_x, tex_clamp_y);
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map clamping rectangle to unit square.
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_translate_x = -clamp_geom_rect.x() / clamp_geom_rect.width();
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_translate_y =
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      -clamp_geom_rect.y() / clamp_geom_rect.height();
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_scale_x = tile_rect.width() / clamp_geom_rect.width();
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_scale_y = tile_rect.height() / clamp_geom_rect.height();
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_, &highp_threshold_cache_, highp_threshold_min_, quad->texture_size);
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform device_transform =
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_transform.FlattenTo2d();
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_transform.IsInvertible())
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float edge[24];
1624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool use_aa =
1625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      settings_->allow_antialiasing &&
1626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f);
1629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GLenum filter = (use_aa || scaled ||
1630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   !quad->quadTransform().IsIdentityOrIntegerTranslation())
1631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      ? GL_LINEAR
1632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      : GL_NEAREST;
1633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL quad_resource_lock(
1634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resource_provider_, resource_id, filter);
1635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SamplerType sampler =
1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      SamplerTypeFromTextureTarget(quad_resource_lock.target());
1637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_translate_x = clamp_tex_rect.x();
1639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_translate_y = clamp_tex_rect.y();
1640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_scale_x = clamp_tex_rect.width();
1641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_scale_y = clamp_tex_rect.height();
1642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Map to normalized texture coordinates.
1644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sampler != SamplerType2DRect) {
1645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Size texture_size = quad->texture_size;
1646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!texture_size.IsEmpty());
1647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_translate_x /= texture_size.width();
1648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_translate_y /= texture_size.height();
1649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_scale_x /= texture_size.width();
1650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_scale_y /= texture_size.height();
1651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TileProgramUniforms uniforms;
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (quad->swizzle_contents) {
1656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      TileUniformLocation(GetTileProgramSwizzleAA(tex_coord_precision, sampler),
1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          &uniforms);
1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
1659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      TileUniformLocation(GetTileProgramAA(tex_coord_precision, sampler),
1660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          &uniforms);
1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (quad->ShouldDrawWithBlending()) {
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (quad->swizzle_contents) {
1665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        TileUniformLocation(GetTileProgramSwizzle(tex_coord_precision, sampler),
1666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            &uniforms);
1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
1668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(GetTileProgram(tex_coord_precision, sampler),
1669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &uniforms);
1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (quad->swizzle_contents) {
1673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(
1674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            GetTileProgramSwizzleOpaque(tex_coord_precision, sampler),
1675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            &uniforms);
1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
1677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(GetTileProgramOpaque(tex_coord_precision, sampler),
1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            &uniforms);
1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(uniforms.program);
1684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(uniforms.sampler_location, 0));
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
1687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
1692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
1693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.vertex_tex_transform_location,
1696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_x,
1697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_y,
1698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_x,
1699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_y));
1700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.fragment_tex_transform_location,
1702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_translate_x,
1703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_translate_y,
1704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_scale_x,
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_scale_y));
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move fragment shader transform to vertex shader. We can do this while
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // still producing correct results as fragment_tex_transform_location
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // should always be non-negative when tiles are transformed in a way
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // that could result in sampling outside the layer.
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_scale_x *= fragment_tex_scale_x;
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_scale_y *= fragment_tex_scale_y;
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_x *= fragment_tex_scale_x;
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_y *= fragment_tex_scale_y;
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_x += fragment_tex_translate_x;
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_y += fragment_tex_translate_y;
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.vertex_tex_transform_location,
1720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_x,
1721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_y,
1722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_x,
1723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_y));
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable blending when the quad properties require it or if we decided
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to use antialiasing.
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normalize to tile_rect.
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
1734b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetShaderQuadF(local_quad, uniforms.quad_location);
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transform and vertex data are used to figure out the extents that the
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // un-antialiased quad should have and which vertex this is and the float
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad passed in via uniform is the actual geometry that gets used to draw
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it. This is why this centered rect is used and not the original quad_rect.
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF centered_rect(
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tile_rect.size());
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const YUVVideoDrawQuad* quad) {
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool use_alpha_plane = quad->a_plane_resource_id != 0;
17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL y_plane_lock(
1760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->y_plane_resource_id, GL_TEXTURE1, GL_LINEAR);
1761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), y_plane_lock.target());
17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL u_plane_lock(
1763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->u_plane_resource_id, GL_TEXTURE2, GL_LINEAR);
1764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), u_plane_lock.target());
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL v_plane_lock(
1766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->v_plane_resource_id, GL_TEXTURE3, GL_LINEAR);
1767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), v_plane_lock.target());
1768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
1769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane) {
1770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
1771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        resource_provider_, quad->a_plane_resource_id, GL_TEXTURE4, GL_LINEAR));
1772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), a_plane_lock->target());
1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int matrix_location = -1;
1776effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int tex_scale_location = -1;
1777effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int tex_offset_location = -1;
1778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int y_texture_location = -1;
1779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int u_texture_location = -1;
1780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int v_texture_location = -1;
1781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int a_texture_location = -1;
1782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int yuv_matrix_location = -1;
1783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int yuv_adj_location = -1;
1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int alpha_location = -1;
1785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane) {
1786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const VideoYUVAProgram* program = GetVideoYUVAProgram(tex_coord_precision);
1787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(program && (program->initialized() || IsContextLost()));
1788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SetUseProgram(program->program());
1789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
1790effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_scale_location = program->vertex_shader().tex_scale_location();
1791effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_offset_location = program->vertex_shader().tex_offset_location();
1792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    y_texture_location = program->fragment_shader().y_texture_location();
1793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    u_texture_location = program->fragment_shader().u_texture_location();
1794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v_texture_location = program->fragment_shader().v_texture_location();
1795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    a_texture_location = program->fragment_shader().a_texture_location();
1796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
1797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_adj_location = program->fragment_shader().yuv_adj_location();
1798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    alpha_location = program->fragment_shader().alpha_location();
1799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
1800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision);
1801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(program && (program->initialized() || IsContextLost()));
1802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SetUseProgram(program->program());
1803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
1804effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_scale_location = program->vertex_shader().tex_scale_location();
1805effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_offset_location = program->vertex_shader().tex_offset_location();
1806868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    y_texture_location = program->fragment_shader().y_texture_location();
1807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    u_texture_location = program->fragment_shader().u_texture_location();
1808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v_texture_location = program->fragment_shader().v_texture_location();
1809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
1810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_adj_location = program->fragment_shader().yuv_adj_location();
1811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    alpha_location = program->fragment_shader().alpha_location();
1812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1814a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform2f(tex_scale_location,
1816effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.width(),
1817effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.height()));
1818effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  GLC(gl_,
1819effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      gl_->Uniform2f(tex_offset_location,
1820effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.x(),
1821effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.y()));
1822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(y_texture_location, 1));
1823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(u_texture_location, 2));
1824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(v_texture_location, 3));
1825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane)
1826a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(a_texture_location, 4));
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These values are magic numbers that are used in the transformation from YUV
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to RGB color values.  They are taken from the following webpage:
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.fourcc.org/fccyvrgb.php
1831010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float yuv_to_rgb_rec601[9] = {
1832010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
1833010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
1834010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float yuv_to_rgb_rec601_jpeg[9] = {
1835010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
1836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These values map to 16, 128, and 128 respectively, and are computed
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // They are used in the YUV to RGBA conversion formula:
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   Y - 16   : Gives 16 values of head and footroom for overshooting
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   U - 128  : Turns unsigned U into signed U [-128,127]
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   V - 128  : Turns unsigned V into signed V [-128,127]
1844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float yuv_adjust_rec601[3] = {
1845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      -0.0625f, -0.5f, -0.5f,
1846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
1847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Same as above, but without the head and footroom.
1849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float yuv_adjust_rec601_jpeg[3] = {
1850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      0.0f, -0.5f, -0.5f,
1851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
1852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float* yuv_to_rgb = NULL;
1854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  float* yuv_adjust = NULL;
1855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  switch (quad->color_space) {
1857010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case YUVVideoDrawQuad::REC_601:
1858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      yuv_to_rgb = yuv_to_rgb_rec601;
1859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      yuv_adjust = yuv_adjust_rec601;
1860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
1861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case YUVVideoDrawQuad::REC_601_JPEG:
1862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      yuv_to_rgb = yuv_to_rgb_rec601_jpeg;
1863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      yuv_adjust = yuv_adjust_rec601_jpeg;
1864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      break;
1865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1866010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1867010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
1868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust));
1869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetShaderOpacity(quad->opacity(), alpha_location);
1871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DrawQuadGeometry(frame, quad->quadTransform(), quad->rect, matrix_location);
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const StreamVideoDrawQuad* quad) {
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(capabilities_.using_egl_image);
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1883a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
1887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoStreamTextureProgram* program =
1889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetVideoStreamTextureProgram(tex_coord_precision);
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ToGLMatrix(&gl_matrix[0], quad->matrix);
1893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          program->vertex_shader().tex_matrix_location(), 1, false, gl_matrix));
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
1898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          quad->resource_id);
1899116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
1900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id()));
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(),
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->fragment_shader().alpha_location());
19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(frame,
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->quadTransform(),
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->rect,
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->vertex_shader().matrix_location());
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawPictureQuad(const DrawingFrame* frame,
1913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const PictureDrawQuad* quad) {
1914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (on_demand_tile_raster_bitmap_.width() != quad->texture_size.width() ||
1915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      on_demand_tile_raster_bitmap_.height() != quad->texture_size.height()) {
1916effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    on_demand_tile_raster_bitmap_.allocN32Pixels(quad->texture_size.width(),
1917effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                 quad->texture_size.height());
1918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (on_demand_tile_raster_resource_id_)
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    on_demand_tile_raster_resource_id_ = resource_provider_->CreateGLTexture(
192303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        quad->texture_size,
192403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GL_TEXTURE_2D,
192503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
192603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GL_CLAMP_TO_EDGE,
192703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ResourceProvider::TextureHintImmutable,
192803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        quad->texture_format);
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
193103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SkCanvas canvas(on_demand_tile_raster_bitmap_);
193203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  quad->picture_pile->RasterToBitmap(
193303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      &canvas, quad->content_rect, quad->contents_scale, NULL);
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1935d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint8_t* bitmap_pixels = NULL;
1936d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SkBitmap on_demand_tile_raster_bitmap_dest;
1937a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SkColorType colorType = ResourceFormatToSkColorType(quad->texture_format);
1938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (on_demand_tile_raster_bitmap_.colorType() != colorType) {
1939d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    on_demand_tile_raster_bitmap_.copyTo(&on_demand_tile_raster_bitmap_dest,
1940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         colorType);
1941d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
1942d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // bitmap data. This check will be removed once crbug.com/293728 is fixed.
1943d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CHECK_EQ(0u, on_demand_tile_raster_bitmap_dest.rowBytes() % 4);
1944d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bitmap_pixels = reinterpret_cast<uint8_t*>(
1945d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        on_demand_tile_raster_bitmap_dest.getPixels());
1946d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
1947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bitmap_pixels =
1948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        reinterpret_cast<uint8_t*>(on_demand_tile_raster_bitmap_.getPixels());
1949d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
1950d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  resource_provider_->SetPixels(on_demand_tile_raster_resource_id_,
1952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                bitmap_pixels,
1953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Rect(quad->texture_size),
1954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Rect(quad->texture_size),
1955a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Vector2d());
1956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawContentQuad(frame, quad, on_demand_tile_raster_resource_id_);
1958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TextureProgramBinding {
19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class Program>
1962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Set(Program* program) {
1963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(program);
19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_id = program->program();
19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sampler_location = program->fragment_shader().sampler_location();
19662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
19677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    background_color_location =
19687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        program->fragment_shader().background_color_location();
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int program_id;
19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int sampler_location;
19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int matrix_location;
19737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int background_color_location;
19742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TexTransformTextureProgramBinding : TextureProgramBinding {
19772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class Program>
1978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Set(Program* program) {
1979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TextureProgramBinding::Set(program);
19802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tex_transform_location = program->vertex_shader().tex_transform_location();
19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_opacity_location =
19822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().vertex_opacity_location();
19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int tex_transform_location;
19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int vertex_opacity_location;
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::FlushTextureQuadCache() {
19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check to see if we have anything to draw.
19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_cache_.program_id == 0)
19912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the correct blending mode.
19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(draw_cache_.needs_blending);
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind the program to the GL state.
19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(draw_cache_.program_id);
19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind the correct texture sampler location.
2000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(draw_cache_.sampler_location, 0));
20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Assume the current active textures is 0.
20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL locked_quad(resource_provider_,
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 draw_cache_.resource_id);
2005116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
2006a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, locked_quad.texture_id()));
20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed);
2009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float),
2010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 struct_is_densely_packed);
20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Upload the tranforms for both points and uvs.
2013a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2014a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.matrix_location),
20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.matrix_data.size()),
20172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          false,
20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<float*>(&draw_cache_.matrix_data.front())));
2019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2020a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4fv(
20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.uv_xform_location),
20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.uv_xform_data.size()),
20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<float*>(&draw_cache_.uv_xform_data.front())));
20247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
20257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (draw_cache_.background_color != SK_ColorTRANSPARENT) {
20267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Float4 background_color = PremultipliedColor(draw_cache_.background_color);
2027a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4fv(
20297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            draw_cache_.background_color_location, 1, background_color.data));
20307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
20317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2033a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform1fv(
20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.vertex_opacity_location),
20352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.vertex_opacity_data.size()),
20362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<float*>(&draw_cache_.vertex_opacity_data.front())));
20372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw the quads!
2039a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2040a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->DrawElements(GL_TRIANGLES,
2041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        6 * draw_cache_.matrix_data.size(),
2042a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        GL_UNSIGNED_SHORT,
2043a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        0));
20442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear the cache.
20462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.program_id = 0;
20472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.uv_xform_data.resize(0);
20482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.resize(0);
20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.matrix_data.resize(0);
20502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
20532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const TextureDrawQuad* quad) {
2054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
2056a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
2057a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
2058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
2059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Choose the correct texture program binding
20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TexTransformTextureProgramBinding binding;
2062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (quad->premultiplied_alpha) {
20637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (quad->background_color == SK_ColorTRANSPARENT) {
2064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetTextureProgram(tex_coord_precision));
20657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
2066f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetTextureBackgroundProgram(tex_coord_precision));
20677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
20697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (quad->background_color == SK_ColorTRANSPARENT) {
2070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetNonPremultipliedTextureProgram(tex_coord_precision));
20717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
20727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      binding.Set(
2073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          GetNonPremultipliedTextureBackgroundProgram(tex_coord_precision));
20747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resource_id = quad->resource_id;
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_cache_.program_id != binding.program_id ||
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.resource_id != resource_id ||
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.needs_blending != quad->ShouldDrawWithBlending() ||
20827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      draw_cache_.background_color != quad->background_color ||
20832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.matrix_data.size() >= 8) {
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FlushTextureQuadCache();
20852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.program_id = binding.program_id;
20862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.resource_id = resource_id;
20872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.needs_blending = quad->ShouldDrawWithBlending();
20887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    draw_cache_.background_color = quad->background_color;
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.uv_xform_location = binding.tex_transform_location;
20917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    draw_cache_.background_color_location = binding.background_color_location;
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.vertex_opacity_location = binding.vertex_opacity_location;
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.matrix_location = binding.matrix_location;
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.sampler_location = binding.sampler_location;
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the uv-transform
2098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  draw_cache_.uv_xform_data.push_back(UVTransform(quad));
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the vertex opacity
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const float opacity = quad->opacity();
21022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity);
21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity);
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity);
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[3] * opacity);
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the transform matrix
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
2110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  quad_rect_matrix = frame->projection_matrix * quad_rect_matrix;
21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Float16 m;
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  quad_rect_matrix.matrix().asColMajorf(m.data);
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.matrix_data.push_back(m);
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const IOSurfaceDrawQuad* quad) {
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
2123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
2124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
2125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
2126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TexTransformTextureProgramBinding binding;
2128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  binding.Set(GetTextureIOSurfaceProgram(tex_coord_precision));
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(binding.program_id);
2131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(binding.sampler_location, 0));
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) {
2133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(binding.tex_transform_location,
2135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height(),
2137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.width(),
2138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height() * -1.0f));
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(binding.tex_transform_location,
2142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.width(),
2145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height()));
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const float vertex_opacity[] = {quad->opacity(), quad->opacity(),
2149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  quad->opacity(), quad->opacity()};
2150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1fv(binding.vertex_opacity_location, 4, vertex_opacity));
21512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
2153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          quad->io_surface_resource_id);
2154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
2155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id()));
21562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
21582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), quad->rect, binding.matrix_location);
21592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0));
21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) {
21640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (use_sync_query_) {
21650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(current_sync_query_);
21660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    current_sync_query_->End();
21670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_sync_queries_.push_back(current_sync_query_.Pass());
21680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
21690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
2171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  swap_buffer_rect_.Union(gfx::ToEnclosingRect(frame->root_damage_rect));
21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_BLEND));
21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  blend_shadow_ = false;
2175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ScheduleOverlays(frame);
21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); }
21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::FlippedFramebuffer() const { return true; }
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureScissorTestEnabled() {
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_scissor_enabled_)
21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureScissorTestDisabled() {
21932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_scissor_enabled_)
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = false;
21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::CopyCurrentRenderPassToBitmap(
2202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
220390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
22045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::CopyCurrentRenderPassToBitmap");
2205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::Rect copy_rect = frame->current_render_pass->output_rect;
2206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (request->has_area())
2207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    copy_rect.Intersect(request->area());
2208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetFramebufferPixelsAsync(copy_rect, request.Pass());
2209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) {
22122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.matrix().asColMajorf(gl_matrix);
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) {
22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad_location == -1)
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
22182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  float gl_quad[8];
2220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[0] = quad.p1().x();
2221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[1] = quad.p1().y();
2222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[2] = quad.p2().x();
2223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[3] = quad.p2().y();
2224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[4] = quad.p3().x();
2225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[5] = quad.p3().y();
2226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[6] = quad.p4().x();
2227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[7] = quad.p4().y();
2228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform2fv(quad_location, 4, gl_quad));
22292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetShaderOpacity(float opacity, int alpha_location) {
22322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alpha_location != -1)
2233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1f(alpha_location, opacity));
22342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2236fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid GLRenderer::SetStencilEnabled(bool enabled) {
2237fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  if (enabled == stencil_shadow_)
2238fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    return;
2239fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
2240fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  if (enabled)
2241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
2242fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  else
2243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
2244fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  stencil_shadow_ = enabled;
2245fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
2246fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
22472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetBlendEnabled(bool enabled) {
22482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled == blend_shadow_)
22492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
22502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled)
2252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Enable(GL_BLEND));
22532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
2254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Disable(GL_BLEND));
22552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  blend_shadow_ = enabled;
22562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetUseProgram(unsigned program) {
22592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (program == program_shadow_)
22602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->UseProgram(program);
22622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program_shadow_ = program;
22632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawQuadGeometry(const DrawingFrame* frame,
22662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Transform& draw_transform,
22672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::RectF& quad_rect,
22682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  int matrix_location) {
22692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
22702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, draw_transform, quad_rect);
22712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
2272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad_rect_matrix);
2273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->UniformMatrix4fv(matrix_location, 1, false, &gl_matrix[0]));
22742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
22762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame,
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          int texture_id,
22805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const gfx::Rect& rect,
22817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                          const gfx::Transform& draw_matrix,
22827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                          bool flip_vertically) {
2283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
22857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const RenderPassProgram* program = GetRenderPassProgram(tex_coord_precision);
22877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetUseProgram(program->program());
22882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
22902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (flip_vertically) {
2292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
2294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       -1.f));
22987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
2299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
2301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f));
23057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
23067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
23077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetShaderOpacity(1.f, program->fragment_shader().alpha_location());
2308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
2309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
23102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
23112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, draw_matrix, rect, program->vertex_shader().matrix_location());
23122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::Finish() {
23158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::Finish");
2316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Finish());
23172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
23202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!is_backbuffer_discarded_);
23212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc,benchmark", "GLRenderer::SwapBuffers");
23232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We're done! Time to swapbuffers!
23242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Size surface_size = output_surface_->SurfaceSize();
2326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
23275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  CompositorFrame compositor_frame;
2328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  compositor_frame.metadata = metadata;
23295e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  compositor_frame.gl_frame_data = make_scoped_ptr(new GLFrameData);
2330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  compositor_frame.gl_frame_data->size = surface_size;
233158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (capabilities_.using_partial_swap) {
23322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If supported, we can save significant bandwidth by only swapping the
2333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // damaged/scissored region (clamped to the viewport).
2334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    swap_buffer_rect_.Intersect(gfx::Rect(surface_size));
2335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int flipped_y_pos_of_rect_bottom = surface_size.height() -
2336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       swap_buffer_rect_.y() -
2337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       swap_buffer_rect_.height();
23385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    compositor_frame.gl_frame_data->sub_buffer_rect =
23395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)        gfx::Rect(swap_buffer_rect_.x(),
23405e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  flipped_y_pos_of_rect_bottom,
23415e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  swap_buffer_rect_.width(),
23425e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  swap_buffer_rect_.height());
23432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
23445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    compositor_frame.gl_frame_data->sub_buffer_rect =
23455e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)        gfx::Rect(output_surface_->SurfaceSize());
23462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23475e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  output_surface_->SwapBuffers(&compositor_frame);
23482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Release previously used overlay resources and hold onto the pending ones
2350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // until the next swap buffers.
2351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.clear();
2352effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.swap(pending_overlay_resources_);
2353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
23542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  swap_buffer_rect_ = gfx::Rect();
23552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnforceMemoryPolicy() {
23585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!visible()) {
23592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::EnforceMemoryPolicy dropping resources");
23602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReleaseRenderPassTextures();
23610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DiscardBackbuffer();
23622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->ReleaseCachedData();
23635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    output_surface_->context_provider()->DeleteCachedResources();
2364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Flush());
23652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::DiscardBackbuffer() {
23692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_backbuffer_discarded_)
23702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
23712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->DiscardBackbuffer();
23732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_backbuffer_discarded_ = true;
23752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Damage tracker needs a full reset every time framebuffer is discarded.
23772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->SetFullRootLayerDamage();
23782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureBackbuffer() {
23812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_backbuffer_discarded_)
23822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
23832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->EnsureBackbuffer();
23852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_backbuffer_discarded_ = false;
23862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
238890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GLRenderer::GetFramebufferPixelsAsync(
23895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& rect,
2390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
239190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!request->IsEmpty());
239290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (request->IsEmpty())
2393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
239490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (rect.IsEmpty())
2395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
2398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GE(window_rect.x(), 0);
2399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GE(window_rect.y(), 0);
2400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_LE(window_rect.right(), current_surface_size_.width());
2401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
24027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
24037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!request->force_bitmap_result()) {
2404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool own_mailbox = !request->has_texture_mailbox();
2405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint texture_id = 0;
24077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gpu::Mailbox mailbox;
2408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (own_mailbox) {
2409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->GenMailboxCHROMIUM(mailbox.name));
24105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      gl_->GenTextures(1, &texture_id);
24115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
2412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(
2419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
2420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(
2422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
2423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
2424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
24255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      mailbox = request->texture_mailbox().mailbox();
24265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK_EQ(static_cast<unsigned>(GL_TEXTURE_2D),
24275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                request->texture_mailbox().target());
24285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK(!mailbox.IsZero());
24295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      unsigned incoming_sync_point = request->texture_mailbox().sync_point();
24305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (incoming_sync_point)
24315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        GLC(gl_, gl_->WaitSyncPointCHROMIUM(incoming_sync_point));
24325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
24335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      texture_id = GLC(
24345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          gl_,
24355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
24367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(texture_id, RGBA_8888, window_rect);
24387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    unsigned sync_point = gl_->InsertSyncPointCHROMIUM();
2440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureMailbox texture_mailbox(mailbox, GL_TEXTURE_2D, sync_point);
2441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback;
2443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (own_mailbox) {
24445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
2445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      release_callback = texture_mailbox_deleter_->GetReleaseCallback(
2446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          output_surface_->context_provider(), texture_id);
2447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
2448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->DeleteTextures(1, &texture_id);
2449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
2450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    request->SendTextureResult(
2452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        window_rect.size(), texture_mailbox, release_callback.Pass());
24537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
24547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
24557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
24567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(request->force_bitmap_result());
24577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
245990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pending_read->copy_request = request.Pass();
2460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    pending_read.Pass());
2462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool do_workaround = NeedsIOSurfaceReadbackWorkaround();
24642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned temporary_texture = 0;
2466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned temporary_fbo = 0;
24672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (do_workaround) {
24692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Mac OS X, calling glReadPixels() against an FBO whose color attachment
24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is an IOSurface-backed texture causes corruption of future glReadPixels()
24712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // calls, even those on different OpenGL contexts. It is believed that this
24722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is the root cause of top crasher
24732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // http://crbug.com/99393. <rdar://problem/10949687>
24742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenTextures(1, &temporary_texture);
2476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, temporary_texture));
2477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
2483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
24852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Copy the contents of the current (IOSurface-backed) framebuffer into a
24862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // temporary texture.
2487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(
2488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        temporary_texture, RGBA_8888, gfx::Rect(current_surface_size_));
2489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenFramebuffers(1, &temporary_fbo);
24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attach this texture to an FBO, and perform the readback from that FBO.
2491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, temporary_fbo));
2492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
2494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  GL_COLOR_ATTACHMENT0,
2495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  GL_TEXTURE_2D,
2496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  temporary_texture,
2497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  0));
24987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
24997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
2500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              gl_->CheckFramebufferStatus(GL_FRAMEBUFFER));
25012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint buffer = 0;
2504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->GenBuffers(1, &buffer);
2505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, buffer));
2506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      4 * window_rect.size().GetArea(),
2509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      NULL,
2510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_STREAM_READ));
2511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint query = 0;
2513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gl_->GenQueriesEXT(1, &query);
2514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GLC(gl_, gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, query));
2515a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->ReadPixels(window_rect.x(),
2518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.y(),
2519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.width(),
2520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.height(),
2521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_RGBA,
2522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_UNSIGNED_BYTE,
2523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      NULL));
2524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (do_workaround) {
25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clean up.
2529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
2530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
2531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteFramebuffers(1, &temporary_fbo));
2532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteTextures(1, &temporary_texture));
2533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Closure finished_callback = base::Bind(&GLRenderer::FinishedReadback,
2536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               base::Unretained(this),
2537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               buffer,
2538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               query,
2539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               window_rect.size());
2540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Save the finished_callback so it can be cancelled.
2541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset(
2542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      finished_callback);
25435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Closure cancelable_callback =
25445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pending_async_read_pixels_.front()->
25455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          finished_read_pixels_callback.callback();
2546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Save the buffer to verify the callbacks happen in the expected order.
2548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.front()->buffer = buffer;
2549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GLC(gl_, gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM));
2551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  context_support_->SignalQuery(query, cancelable_callback);
2552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnforceMemoryPolicy();
25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GLRenderer::FinishedReadback(unsigned source_buffer,
2557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  unsigned query,
2558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const gfx::Size& size) {
2559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!pending_async_read_pixels_.empty());
256090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2561a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (query != 0) {
2562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteQueriesEXT(1, &query));
2563a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
2564a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
256590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back();
256690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure we service the readbacks in order.
256790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(source_buffer, current_read->buffer);
2568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8* src_pixels = NULL;
2570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap;
2571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (source_buffer != 0) {
2573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, source_buffer));
2575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    src_pixels = static_cast<uint8*>(gl_->MapBufferCHROMIUM(
2576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
2577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (src_pixels) {
2579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bitmap.reset(new SkBitmap);
2580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bitmap->allocN32Pixels(size.width(), size.height());
2581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
2582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      uint8* dest_pixels = static_cast<uint8*>(bitmap->getPixels());
2583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t row_bytes = size.width() * 4;
2585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int num_rows = size.height();
2586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t total_bytes = num_rows * row_bytes;
2587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
2588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Flip Y axis.
25897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        size_t src_y = total_bytes - dest_y - row_bytes;
2590b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // Swizzle OpenGL -> Skia byte order.
2591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        for (size_t x = 0; x < row_bytes; x += 4) {
2592a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_R32_SHIFT / 8] =
2593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 0];
2594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_G32_SHIFT / 8] =
2595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 1];
2596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_B32_SHIFT / 8] =
2597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 2];
2598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_A32_SHIFT / 8] =
2599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 3];
2600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
2601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
2602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM));
2605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
2607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteBuffers(1, &source_buffer));
2608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (bitmap)
2611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_read->copy_request->SendBitmapResult(bitmap.Pass());
2612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.pop_back();
2613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::GetFramebufferTexture(unsigned texture_id,
2616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       ResourceFormat texture_format,
26175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const gfx::Rect& window_rect) {
26187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(texture_id);
26197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.x(), 0);
26207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.y(), 0);
26217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(window_rect.right(), current_surface_size_.width());
26227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
26232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
2625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->CopyTexImage2D(GL_TEXTURE_2D,
2627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          0,
2628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLDataFormat(texture_format),
2629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.x(),
2630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.y(),
2631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.width(),
2632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.height(),
2633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          0));
2634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
26352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool GLRenderer::UseScopedTexture(DrawingFrame* frame,
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const ScopedResource* texture,
26395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const gfx::Rect& viewport_rect) {
26402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture->id());
2641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  frame->current_render_pass = NULL;
2642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  frame->current_texture = texture;
26432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return BindFramebufferToTexture(frame, texture, viewport_rect);
26452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
26482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->BindFramebuffer();
2650fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
265158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (output_surface_->HasExternalStencilTest()) {
2652fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    SetStencilEnabled(true);
2653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->StencilFunc(GL_EQUAL, 1, 1));
2654fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  } else {
2655fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    SetStencilEnabled(false);
2656fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
26572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const ScopedResource* texture,
26615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const gfx::Rect& target_rect) {
26622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture->id());
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2664b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_framebuffer_lock_.reset();
2665b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2666fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SetStencilEnabled(false);
2667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_));
26682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_ =
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL(
26702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_provider_, texture->id()));
26712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned texture_id = current_framebuffer_lock_->texture_id();
2672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->FramebufferTexture2D(
26742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0));
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
2677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             GL_FRAMEBUFFER_COMPLETE ||
2678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         IsContextLost());
26792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeViewport(
2681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      frame, target_rect, gfx::Rect(target_rect.size()), target_rect.size());
26822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnsureScissorTestEnabled();
26872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't unnecessarily ask the context to change the scissor, because it
26892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // may cause undesired GPU pipeline flushes.
2690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (scissor_rect == scissor_rect_ && !scissor_rect_needs_reset_)
26912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
26922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scissor_rect_ = scissor_rect;
26942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Scissor(scissor_rect.x(),
2697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.y(),
2698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.width(),
2699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.height()));
2700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scissor_rect_needs_reset_ = false;
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GLRenderer::SetDrawViewport(const gfx::Rect& window_space_viewport) {
2705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  viewport_ = window_space_viewport;
2706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Viewport(window_space_viewport.x(),
2708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.y(),
2709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.width(),
2710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.height()));
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::InitializeSharedObjects() {
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects");
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create an FBO for doing offscreen rendering.
2717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->GenFramebuffers(1, &offscreen_framebuffer_id_));
27182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  shared_geometry_ = make_scoped_ptr(
2720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new GeometryBinding(gl_, QuadVertexRect()));
27212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::TileCheckerboardProgram*
27242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::GetTileCheckerboardProgram() {
2725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!tile_checkerboard_program_.initialized()) {
27262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::checkerboardProgram::initalize");
2727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    tile_checkerboard_program_.Initialize(output_surface_->context_provider(),
2728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          TexCoordPrecisionNA,
2729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          SamplerTypeNA);
27302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &tile_checkerboard_program_;
27322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::DebugBorderProgram* GLRenderer::GetDebugBorderProgram() {
2735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!debug_border_program_.initialized()) {
27362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::debugBorderProgram::initialize");
2737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    debug_border_program_.Initialize(output_surface_->context_provider(),
2738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     TexCoordPrecisionNA,
2739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     SamplerTypeNA);
27402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &debug_border_program_;
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::SolidColorProgram* GLRenderer::GetSolidColorProgram() {
2745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!solid_color_program_.initialized()) {
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::solidColorProgram::initialize");
2747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    solid_color_program_.Initialize(output_surface_->context_provider(),
2748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    TexCoordPrecisionNA,
2749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    SamplerTypeNA);
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &solid_color_program_;
27522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() {
2755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!solid_color_program_aa_.initialized()) {
27562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::solidColorProgramAA::initialize");
2757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    solid_color_program_aa_.Initialize(output_surface_->context_provider(),
2758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       TexCoordPrecisionNA,
2759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       SamplerTypeNA);
27602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &solid_color_program_aa_;
27622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram(
2765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassProgram* program = &render_pass_program_[precision];
2769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize");
2771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA(
2778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassProgramAA* program = &render_pass_program_aa_[precision];
2782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize");
2784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
27882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const GLRenderer::RenderPassMaskProgram* GLRenderer::GetRenderPassMaskProgram(
2791a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskProgram* program = &render_pass_mask_program_[precision];
2795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize");
2797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::RenderPassMaskProgramAA*
2804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision) {
2805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskProgramAA* program = &render_pass_mask_program_aa_[precision];
2808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
28092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize");
2810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassColorMatrixProgram*
2817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision) {
2818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassColorMatrixProgram* program =
2821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_color_matrix_program_[precision];
2822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
2824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassColorMatrixProgramAA*
2831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
2832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassColorMatrixProgramAA* program =
2835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_color_matrix_program_aa_[precision];
2836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassColorMatrixProgramAA::initialize");
2839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassMaskColorMatrixProgram*
2846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
2847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskColorMatrixProgram* program =
2850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_mask_color_matrix_program_[precision];
2851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
2854f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2855f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2857f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassMaskColorMatrixProgramAA*
2861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
2862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskColorMatrixProgramAA* program =
2865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_mask_color_matrix_program_aa_[precision];
2866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
2869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
28712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2872f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgram* GLRenderer::GetTileProgram(
2876a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2877a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgram* program = &tile_program_[precision][sampler];
2883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
28842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgram::initialize");
2885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
28872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramOpaque* GLRenderer::GetTileProgramOpaque(
2892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramOpaque* program = &tile_program_opaque_[precision][sampler];
2899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramOpaque::initialize");
2901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramAA* GLRenderer::GetTileProgramAA(
2908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2909a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramAA* program = &tile_program_aa_[precision][sampler];
2915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramAA::initialize");
2917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramSwizzle* GLRenderer::GetTileProgramSwizzle(
2924a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2929f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramSwizzle* program = &tile_program_swizzle_[precision][sampler];
2931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzle::initialize");
2933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2936f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::TileProgramSwizzleOpaque*
2940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLRenderer::GetTileProgramSwizzleOpaque(TexCoordPrecision precision,
2941a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        SamplerType sampler) {
2942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2943f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2944f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramSwizzleOpaque* program =
2947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &tile_program_swizzle_opaque_[precision][sampler];
2948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleOpaque::initialize");
2950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2953f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramSwizzleAA* GLRenderer::GetTileProgramSwizzleAA(
2957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2963a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TileProgramSwizzleAA* program = &tile_program_swizzle_aa_[precision][sampler];
2964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleAA::initialize");
2966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram(
2973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TexCoordPrecision precision) {
2974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureProgram* program = &texture_program_[precision];
2977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
2979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
29812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst GLRenderer::NonPremultipliedTextureProgram*
2986a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLRenderer::GetNonPremultipliedTextureProgram(TexCoordPrecision precision) {
2987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NonPremultipliedTextureProgram* program =
2990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &nonpremultiplied_texture_program_[precision];
2991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT0("cc",
2993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
2994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
29962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst GLRenderer::TextureBackgroundProgram*
30017dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochGLRenderer::GetTextureBackgroundProgram(TexCoordPrecision precision) {
3002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureBackgroundProgram* program = &texture_background_program_[precision];
30057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!program->initialized()) {
30067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
3007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
30097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
30127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
30137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst GLRenderer::NonPremultipliedTextureBackgroundProgram*
30147dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochGLRenderer::GetNonPremultipliedTextureBackgroundProgram(
30157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TexCoordPrecision precision) {
3016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NonPremultipliedTextureBackgroundProgram* program =
3019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &nonpremultiplied_texture_background_program_[precision];
30207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!program->initialized()) {
30217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT0("cc",
30227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
3023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
30257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
30287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3029a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const GLRenderer::TextureProgram* GLRenderer::GetTextureIOSurfaceProgram(
3030a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
3031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureProgram* program = &texture_io_surface_program_[precision];
3034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::textureIOSurfaceProgram::initialize");
3036f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2DRect);
30382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram(
3043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TexCoordPrecision precision) {
3044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3045f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoYUVProgram* program = &video_yuv_program_[precision];
3047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize");
3049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3050f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
30512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const GLRenderer::VideoYUVAProgram* GLRenderer::GetVideoYUVAProgram(
3056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TexCoordPrecision precision) {
3057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoYUVAProgram* program = &video_yuva_program_[precision];
3060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!program->initialized()) {
3061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::videoYUVAProgram::initialize");
3062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
3064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
3065f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
3066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::VideoStreamTextureProgram*
3069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetVideoStreamTextureProgram(TexCoordPrecision precision) {
30702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Capabilities().using_egl_image)
30712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
3072f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3074f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoStreamTextureProgram* program =
3075f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &video_stream_texture_program_[precision];
3076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::streamTextureProgram::initialize");
3078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3079a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        output_surface_->context_provider(), precision, SamplerTypeExternalOES);
30802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::CleanupSharedObjects() {
30852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shared_geometry_.reset();
30862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3087f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < NumTexCoordPrecisions; ++i) {
3088f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (int j = 0; j < NumSamplerTypes; ++j) {
3089a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_[i][j].Cleanup(gl_);
3090a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_opaque_[i][j].Cleanup(gl_);
3091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_[i][j].Cleanup(gl_);
3092a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_opaque_[i][j].Cleanup(gl_);
3093a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_aa_[i][j].Cleanup(gl_);
3094a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_aa_[i][j].Cleanup(gl_);
3095f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
3096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3097a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_program_[i].Cleanup(gl_);
3098a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_program_[i].Cleanup(gl_);
3099a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_program_aa_[i].Cleanup(gl_);
3100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_program_aa_[i].Cleanup(gl_);
3101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_color_matrix_program_[i].Cleanup(gl_);
3102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_color_matrix_program_aa_[i].Cleanup(gl_);
3103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_color_matrix_program_aa_[i].Cleanup(gl_);
3104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_color_matrix_program_[i].Cleanup(gl_);
3105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_program_[i].Cleanup(gl_);
3107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    nonpremultiplied_texture_program_[i].Cleanup(gl_);
3108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_background_program_[i].Cleanup(gl_);
3109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    nonpremultiplied_texture_background_program_[i].Cleanup(gl_);
3110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_io_surface_program_[i].Cleanup(gl_);
3111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_yuv_program_[i].Cleanup(gl_);
3113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_yuva_program_[i].Cleanup(gl_);
3114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_stream_texture_program_[i].Cleanup(gl_);
3115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  tile_checkerboard_program_.Cleanup(gl_);
3118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  debug_border_program_.Cleanup(gl_);
3120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  solid_color_program_.Cleanup(gl_);
3121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  solid_color_program_aa_.Cleanup(gl_);
31222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offscreen_framebuffer_id_)
3124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_));
31252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (on_demand_tile_raster_resource_id_)
3127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
3128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReleaseRenderPassTextures();
31302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
313290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GLRenderer::ReinitializeGLState() {
31335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  is_scissor_enabled_ = false;
31345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scissor_rect_needs_reset_ = true;
31355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stencil_shadow_ = false;
31365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  blend_shadow_ = true;
31375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  program_shadow_ = 0;
31385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RestoreGLState();
31405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
31415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid GLRenderer::RestoreGLState() {
31435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This restores the current GLRenderer state to the GL context.
31445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
314590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shared_geometry_->PrepareForDraw();
314690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_DEPTH_TEST));
3148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_CULL_FACE));
3149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->ColorMask(true, true, true, true));
3150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
3151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
315290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (program_shadow_)
31545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    gl_->UseProgram(program_shadow_);
31555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (stencil_shadow_)
31575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
31585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else
31595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
31605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (blend_shadow_)
31625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Enable(GL_BLEND));
31635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else
31645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Disable(GL_BLEND));
31655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (is_scissor_enabled_) {
31675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
31685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_,
31695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        gl_->Scissor(scissor_rect_.x(),
31705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scissor_rect_.y(),
31715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scissor_rect_.width(),
31725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     scissor_rect_.height()));
31735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
31745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
31755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
31765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
31775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
31785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid GLRenderer::RestoreFramebuffer(DrawingFrame* frame) {
31795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  UseRenderPass(frame, frame->current_render_pass);
318090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
318190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::IsContextLost() {
3183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return output_surface_->context_provider()->IsContextLost();
31842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
3187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!frame->overlay_list.size())
3188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
3189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ResourceProvider::ResourceIdArray resources;
3191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OverlayCandidateList& overlays = frame->overlay_list;
3192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OverlayCandidateList::iterator it;
3193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  for (it = overlays.begin(); it != overlays.end(); ++it) {
3194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const OverlayCandidate& overlay = *it;
3195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Skip primary plane.
3196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (overlay.plane_z_order == 0)
3197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      continue;
3198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    pending_overlay_resources_.push_back(
3200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        make_scoped_ptr(new ResourceProvider::ScopedReadLockGL(
32015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            resource_provider_, overlay.resource_id)));
3202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_support_->ScheduleOverlayPlane(
3204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.plane_z_order,
3205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.transform,
3206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        pending_overlay_resources_.back()->texture_id(),
3207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.display_rect,
3208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.uv_rect);
3209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
3210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
3211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
32122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
3213