gl_renderer.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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 "base/strings/string_split.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/stringprintf.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_layer_impl.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_metadata.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/output/copy_output_request.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/geometry_binding.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_frame_data.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/render_surface_filters.h"
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/quads/picture_draw_quad.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/render_pass.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/stream_video_draw_quad.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/texture_draw_quad.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/layer_quad.h"
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "cc/resources/raster_worker_pool.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/scoped_resource.h"
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/resources/texture_mailbox_deleter.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/damage_tracker.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/proxy.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "gpu/command_buffer/client/context_support.h"
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/common/gpu_memory_allocation.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/core/SkColorFilter.h"
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkSurface.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/GrContext.h"
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/GrTexture.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/SkGpuDevice.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/gpu/SkGrTexturePixelRef.h"
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/quad_f.h"
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using gpu::gles2::GLES2Interface;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass FallbackFence : public ResourceProvider::Fence {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit FallbackFence(gpu::gles2::GLES2Interface* gl)
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : gl_(gl), has_passed_(false) {}
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Overridden from ResourceProvider::Fence:
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual bool HasPassed() OVERRIDE {
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!has_passed_) {
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      has_passed_ = true;
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      Synchronize();
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return true;
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~FallbackFence() {}
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void Synchronize() {
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    TRACE_EVENT0("cc", "FallbackFence::Synchronize");
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->Finish();
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gpu::gles2::GLES2Interface* gl_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_passed_;
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FallbackFence);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass OnDemandRasterTaskImpl : public Task {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnDemandRasterTaskImpl(PicturePileImpl* picture_pile,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         SkBitmap* bitmap,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         gfx::Rect content_rect,
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         float contents_scale)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : picture_pile_(picture_pile),
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bitmap_(bitmap),
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content_rect_(content_rect),
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        contents_scale_(contents_scale) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(picture_pile_);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(bitmap_);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from Task:
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void RunOnWorkerThread() OVERRIDE {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TRACE_EVENT0("cc", "OnDemandRasterTaskImpl::RunOnWorkerThread");
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SkCanvas canvas(*bitmap_);
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PicturePileImpl* picture_pile = picture_pile_->GetCloneForDrawingOnThread(
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        RasterWorkerPool::GetPictureCloneIndexForCurrentThread());
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(picture_pile);
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    picture_pile->RasterToBitmap(&canvas, content_rect_, contents_scale_, NULL);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~OnDemandRasterTaskImpl() {}
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PicturePileImpl* picture_pile_;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkBitmap* bitmap_;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::Rect content_rect_;
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const float contents_scale_;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OnDemandRasterTaskImpl);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NeedsIOSurfaceReadbackWorkaround() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This isn't strictly required in DumpRenderTree-mode when Mesa is used,
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // but it doesn't seem to hurt.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFloat4 UVTransform(const TextureDrawQuad* quad) {
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::PointF uv0 = quad->uv_top_left;
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::PointF uv1 = quad->uv_bottom_right;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}};
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (quad->flipped) {
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    xform.data[1] = 1.0f - xform.data[1];
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    xform.data[3] = -xform.data[3];
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return xform;
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFloat4 PremultipliedColor(SkColor color) {
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const float factor = 1.0f / 255.0f;
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const float alpha = SkColorGetA(color) * factor;
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Float4 result = {
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      {SkColorGetR(color) * factor * alpha, SkColorGetG(color) * factor * alpha,
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       SkColorGetB(color) * factor * alpha, alpha}};
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return result;
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SamplerType SamplerTypeFromTextureTarget(GLenum target) {
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (target) {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_2D:
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2D;
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_RECTANGLE_ARB:
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2DRect;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_TEXTURE_EXTERNAL_OES:
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerTypeExternalOES;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NOTREACHED();
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SamplerType2D;
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Smallest unit that impact anti-aliasing output. We use this to
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// determine when anti-aliasing is unnecessary.
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // anonymous namespace
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct GLRenderer::PendingAsyncReadPixels {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingAsyncReadPixels() : buffer(0) {}
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<CopyOutputRequest> copy_request;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::CancelableClosure finished_read_pixels_callback;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned buffer;
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels);
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass GLRenderer::SyncQuery {
1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit SyncQuery(gpu::gles2::GLES2Interface* gl)
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : gl_(gl), query_id_(0u), weak_ptr_factory_(this) {
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->GenQueriesEXT(1, &query_id_);
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~SyncQuery() { gl_->DeleteQueriesEXT(1, &query_id_); }
1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ResourceProvider::Fence> Begin() {
2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(!weak_ptr_factory_.HasWeakPtrs() || !IsPending());
2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Invalidate weak pointer held by old fence.
2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    weak_ptr_factory_.InvalidateWeakPtrs();
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query_id_);
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return make_scoped_refptr<ResourceProvider::Fence>(
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        new Fence(weak_ptr_factory_.GetWeakPtr()));
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void End() { gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM); }
2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool IsPending() {
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    unsigned available = 1;
2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl_->GetQueryObjectuivEXT(
2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return !available;
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  class Fence : public ResourceProvider::Fence {
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch   public:
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    explicit Fence(base::WeakPtr<GLRenderer::SyncQuery> query)
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        : query_(query) {}
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Overridden from ResourceProvider::Fence:
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual bool HasPassed() OVERRIDE {
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return !query_ || !query_->IsPending();
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch   private:
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual ~Fence() {}
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::WeakPtr<SyncQuery> query_;
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Fence);
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gpu::gles2::GLES2Interface* gl_;
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  unsigned query_id_;
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::WeakPtrFactory<SyncQuery> weak_ptr_factory_;
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncQuery);
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<GLRenderer> GLRenderer::Create(
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RendererClient* client,
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const LayerTreeSettings* settings,
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OutputSurface* output_surface,
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ResourceProvider* resource_provider,
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TextureMailboxDeleter* texture_mailbox_deleter,
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int highp_threshold_min) {
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return make_scoped_ptr(new GLRenderer(client,
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        settings,
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        output_surface,
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        resource_provider,
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        texture_mailbox_deleter,
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        highp_threshold_min));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::GLRenderer(RendererClient* client,
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       const LayerTreeSettings* settings,
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       OutputSurface* output_surface,
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       ResourceProvider* resource_provider,
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       TextureMailboxDeleter* texture_mailbox_deleter,
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       int highp_threshold_min)
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : DirectRenderer(client, settings, output_surface, resource_provider),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_framebuffer_id_(0),
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      shared_geometry_quad_(QuadVertexRect()),
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_(output_surface->context_provider()->ContextGL()),
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      context_support_(output_surface->context_provider()->ContextSupport()),
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      texture_mailbox_deleter_(texture_mailbox_deleter),
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_backbuffer_discarded_(false),
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visible_(true),
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      is_scissor_enabled_(false),
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scissor_rect_needs_reset_(true),
274fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      stencil_shadow_(false),
275fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      blend_shadow_(false),
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      highp_threshold_min_(highp_threshold_min),
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      highp_threshold_cache_(0),
2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      use_sync_query_(false),
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      on_demand_tile_raster_resource_id_(0) {
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(gl_);
2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(context_support_);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ContextProvider::Capabilities context_caps =
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      output_surface_->context_provider()->ContextCapabilities();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_partial_swap =
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      settings_->partial_swap_enabled && context_caps.gpu.post_sub_buffer;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!context_caps.gpu.iosurface || context_caps.gpu.texture_rectangle);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.using_egl_image = context_caps.gpu.egl_image_external;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.max_texture_size = resource_provider_->max_texture_size();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.best_texture_format = resource_provider_->best_texture_format();
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The updater can access textures while the GLRenderer is using them.
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.allow_partial_texture_updates = true;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for texture fast paths. Currently we always use MO8 textures,
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so we only need to avoid POT textures if we have an NPOT fast-path.
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.avoid_pow2_textures = context_caps.gpu.fast_npot_mo8_textures;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_offscreen_context3d = true;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  capabilities_.using_map_image =
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      settings_->use_map_image && context_caps.gpu.map_image;
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.using_discard_framebuffer =
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      context_caps.gpu.discard_framebuffer;
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.allow_rasterize_on_demand = true;
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  use_sync_query_ = context_caps.gpu.sync_query;
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeSharedObjects();
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::~GLRenderer() {
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!pending_async_read_pixels_.empty()) {
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back();
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pending_read->finished_read_pixels_callback.Cancel();
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pending_async_read_pixels_.pop_back();
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.clear();
326effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CleanupSharedObjects();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const RendererCapabilitiesImpl& GLRenderer::Capabilities() const {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return capabilities_;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::DebugGLCall(GLES2Interface* gl,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const char* command,
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const char* file,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int line) {
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint error = gl->GetError();
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error != GL_NO_ERROR)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "GL command failed: File: " << file << "\n\tLine " << line
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << "\n\tcommand: " << command << ", error "
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << static_cast<int>(error) << "\n";
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetVisible(bool visible) {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visible_ == visible)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visible_ = visible;
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnforceMemoryPolicy();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  context_support_->SetSurfaceVisible(visible);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SendManagedMemoryStats(size_t bytes_visible,
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        size_t bytes_visible_and_nearby,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        size_t bytes_allocated) {
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gpu::ManagedMemoryStats stats;
3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  stats.bytes_required = bytes_visible;
3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  stats.bytes_nice_to_have = bytes_visible_and_nearby;
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  stats.bytes_allocated = bytes_allocated;
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  stats.backbuffer_requested = !is_backbuffer_discarded_;
3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  context_support_->SendManagedMemoryStats(stats);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void GLRenderer::DiscardPixels(bool has_external_stencil_test,
36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               bool draw_rect_covers_full_surface) {
37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (has_external_stencil_test || !draw_rect_covers_full_surface ||
37168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      !capabilities_.using_discard_framebuffer)
37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool using_default_framebuffer =
37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      !current_framebuffer_lock_ &&
37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      output_surface_->capabilities().uses_default_gl_framebuffer;
37668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  GLenum attachments[] = {static_cast<GLenum>(
37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      using_default_framebuffer ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0_EXT)};
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->DiscardFramebufferEXT(
37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      GL_FRAMEBUFFER, arraysize(attachments), attachments);
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void GLRenderer::ClearFramebuffer(DrawingFrame* frame,
38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  bool has_external_stencil_test) {
384fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // It's unsafe to clear when we have a stencil test because glClear ignores
385fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // stencil.
38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (has_external_stencil_test) {
387fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    DCHECK(!frame->current_render_pass->has_transparent_background);
388fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    return;
389fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
390fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On DEBUG builds, opaque render passes are cleared to blue to easily see
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // regions that were not drawn on the screen.
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (frame->current_render_pass->has_transparent_background)
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 0, 0));
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool always_clear = false;
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  always_clear = true;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (always_clear || frame->current_render_pass->has_transparent_background) {
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GLbitfield clear_bits = GL_COLOR_BUFFER_BIT;
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (always_clear)
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      clear_bits |= GL_STENCIL_BUFFER_BIT;
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->Clear(clear_bits);
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (frame->device_viewport_rect.IsEmpty())
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::BeginDrawingFrame");
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ResourceProvider::Fence> read_lock_fence;
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (use_sync_query_) {
4180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    while (!pending_sync_queries_.empty()) {
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (pending_sync_queries_.front()->IsPending())
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        break;
4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      available_sync_queries_.push_back(pending_sync_queries_.take_front());
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    current_sync_query_ = available_sync_queries_.empty()
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              ? make_scoped_ptr(new SyncQuery(gl_))
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              : available_sync_queries_.take_front();
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    read_lock_fence = current_sync_query_->Begin();
4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    read_lock_fence = make_scoped_refptr(new FallbackFence(gl_));
4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  resource_provider_->SetReadLockFence(read_lock_fence.get());
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(enne): Do we need to reinitialize all of this state per frame?
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ReinitializeGLState();
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::DoNoOp() {
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Flush());
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(quad->rect.Contains(quad->visible_rect));
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->material != DrawQuad::TEXTURE_CONTENT) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FlushTextureQuadCache();
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (quad->material) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::INVALID:
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::CHECKERBOARD:
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad));
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::DEBUG_BORDER:
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::IO_SURFACE_CONTENT:
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DrawQuad::PICTURE_CONTENT:
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad));
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::RENDER_PASS:
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::SOLID_COLOR:
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::STREAM_VIDEO_CONTENT:
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case DrawQuad::SURFACE_CONTENT:
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Surface content should be fully resolved to other quad types before
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // reaching a direct renderer.
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TEXTURE_CONTENT:
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EnqueueTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TILED_CONTENT:
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::YUV_VIDEO_CONTENT:
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawYUVVideoQuad(frame, YUVVideoDrawQuad::MaterialCast(quad));
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const CheckerboardDrawQuad* quad) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TileCheckerboardProgram* program = GetTileCheckerboardProgram();
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(program && (program->initialized() || IsContextLost()));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkColor color = quad->color;
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().color_location(),
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetR(color) * (1.0f / 255.0f),
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetG(color) * (1.0f / 255.0f),
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     SkColorGetB(color) * (1.0f / 255.0f),
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     1));
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int checkerboard_width = 16;
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float frequency = 1.0f / checkerboard_width;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->rect;
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_offset_x = tile_rect.x() % checkerboard_width;
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_offset_y = tile_rect.y() % checkerboard_width;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_x = tile_rect.width();
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_y = tile_rect.height();
516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().tex_transform_location(),
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_offset_x,
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_offset_y,
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_x,
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_y));
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform1f(program->fragment_shader().frequency_location(),
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     frequency));
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(),
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->fragment_shader().alpha_location());
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(frame,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->quadTransform(),
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->rect,
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->vertex_shader().matrix_location());
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const DebugBorderDrawQuad* quad) {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const DebugBorderProgram* program = GetDebugBorderProgram();
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(program && (program->initialized() || IsContextLost()));
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use the full quad_rect for debug quads to not move the edges based on
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // partial swaps.
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect = quad->rect;
5470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gfx::Transform render_matrix;
5480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuadRectTransform(&render_matrix, quad->quadTransform(), layer_rect);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLRenderer::ToGLMatrix(&gl_matrix[0],
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         frame->projection_matrix * render_matrix);
551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          program->vertex_shader().matrix_location(), 1, false, &gl_matrix[0]));
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkColor color = quad->color;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float alpha = SkColorGetA(color) * (1.0f / 255.0f);
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(program->fragment_shader().color_location(),
560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     alpha));
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->LineWidth(quad->width));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The indices for the line are stored in the same array as the triangle
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // indices.
569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0));
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static SkBitmap ApplyImageFilter(GLRenderer* renderer,
573424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                 ContextProvider* offscreen_contexts,
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const gfx::Point& origin,
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 SkImageFilter* filter,
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 ScopedResource* source_texture_resource) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!filter)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SkBitmap();
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!offscreen_contexts || !offscreen_contexts->GrContext())
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SkBitmap();
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
583c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ResourceProvider::ScopedReadLockGL lock(renderer->resource_provider(),
584c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          source_texture_resource->id());
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush the compositor context to ensure that textures there are available
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in the shared context.  Do this after locking/creating the compositor
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // texture.
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renderer->resource_provider()->Flush();
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Wrap the source texture in a Ganesh platform texture.
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrBackendTextureDesc backend_texture_description;
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fWidth = source_texture_resource->size().width();
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fHeight =
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_texture_resource->size().height();
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_texture_description.fTextureHandle = lock.texture_id();
5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<GrTexture> texture =
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          backend_texture_description));
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SkImageInfo info = {
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    source_texture_resource->size().width(),
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    source_texture_resource->size().height(),
606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPMColor_SkColorType,
607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPremul_SkAlphaType
608a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  };
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Place the platform texture inside an SkBitmap.
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap source;
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  source.setConfig(info);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> pixel_ref =
613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(info, texture.get()));
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source.setPixelRef(pixel_ref.get());
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a scratch texture for backing store.
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrTextureDesc desc;
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fSampleCnt = 0;
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fWidth = source.width();
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fHeight = source.height();
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  desc.fConfig = kSkia8888_GrPixelConfig;
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GrAutoScratchTexture scratch_texture(
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<GrTexture> backing_store =
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      skia::AdoptRef(scratch_texture.detach());
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a device and canvas using that backing store.
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get());
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkCanvas canvas(&device);
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw the source bitmap through the filter to the canvas.
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPaint paint;
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setImageFilter(filter);
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas.clear(SK_ColorTRANSPARENT);
637424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
638424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // TODO(senorblanco): in addition to the origin translation here, the canvas
639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // should also be scaled to accomodate device pixel ratio and pinch zoom. See
640424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // crbug.com/281516 and crbug.com/281518.
641424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  canvas.translate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y()));
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas.drawSprite(source, 0, 0, &paint);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush skia context so that all the rendered stuff appears on the
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // texture.
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  offscreen_contexts->GrContext()->flush();
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush the GL context so rendering results from this context are
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible in the compositor's context.
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  offscreen_contexts->ContextGL()->Flush();
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return device.accessBitmap(false);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SkBitmap ApplyBlendModeWithBackdrop(
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GLRenderer* renderer,
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ContextProvider* offscreen_contexts,
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkBitmap source_bitmap_with_filters,
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedResource* source_texture_resource,
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedResource* background_texture_resource,
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkXfermode::Mode blend_mode) {
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!offscreen_contexts || !offscreen_contexts->GrContext())
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return source_bitmap_with_filters;
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(background_texture_resource);
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(source_texture_resource);
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Size source_size = source_texture_resource->size();
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Size background_size = background_texture_resource->size();
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LE(background_size.width(), source_size.width());
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LE(background_size.height(), source_size.height());
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int source_texture_with_filters_id;
675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (source_bitmap_with_filters.getTexture()) {
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(source_size.width(), source_bitmap_with_filters.width());
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(source_size.height(), source_bitmap_with_filters.height());
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GrTexture* texture =
680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        reinterpret_cast<GrTexture*>(source_bitmap_with_filters.getTexture());
681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    source_texture_with_filters_id = texture->getTextureHandle();
682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    lock.reset(new ResourceProvider::ScopedReadLockGL(
684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        renderer->resource_provider(), source_texture_resource->id()));
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    source_texture_with_filters_id = lock->texture_id();
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock_background(
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      renderer->resource_provider(), background_texture_resource->id());
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flush the compositor context to ensure that textures there are available
692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // in the shared context.  Do this after locking/creating the compositor
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // texture.
694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  renderer->resource_provider()->Flush();
695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Wrap the source texture in a Ganesh platform texture.
697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrBackendTextureDesc backend_texture_description;
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fWidth = source_size.width();
702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fHeight = source_size.height();
703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fTextureHandle = source_texture_with_filters_id;
704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> source_texture =
705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          backend_texture_description));
707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fWidth = background_size.width();
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fHeight = background_size.height();
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  backend_texture_description.fTextureHandle = lock_background.texture_id();
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> background_texture =
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          backend_texture_description));
714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SkImageInfo source_info = {
716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    source_size.width(),
717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    source_size.height(),
718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPMColor_SkColorType,
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPremul_SkAlphaType
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  };
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Place the platform texture inside an SkBitmap.
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkBitmap source;
723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  source.setConfig(source_info);
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> source_pixel_ref =
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(source_info, source_texture.get()));
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  source.setPixelRef(source_pixel_ref.get());
727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SkImageInfo background_info = {
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    background_size.width(),
730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    background_size.height(),
731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPMColor_SkColorType,
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    kPremul_SkAlphaType
733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  };
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkBitmap background;
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  background.setConfig(background_info);
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<SkGrPixelRef> background_pixel_ref =
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      skia::AdoptRef(new SkGrPixelRef(
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          background_info, background_texture.get()));
740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  background.setPixelRef(background_pixel_ref.get());
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a scratch texture for backing store.
743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrTextureDesc desc;
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fSampleCnt = 0;
746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fWidth = source.width();
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fHeight = source.height();
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fConfig = kSkia8888_GrPixelConfig;
749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GrAutoScratchTexture scratch_texture(
751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch);
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  skia::RefPtr<GrTexture> backing_store =
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      skia::AdoptRef(scratch_texture.detach());
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a device and canvas using that backing store.
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get());
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkCanvas canvas(&device);
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Draw the source bitmap through the filter to the canvas.
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  canvas.clear(SK_ColorTRANSPARENT);
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  canvas.drawSprite(background, 0, 0);
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkPaint paint;
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  paint.setXfermodeMode(blend_mode);
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  canvas.drawSprite(source, 0, 0, &paint);
765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flush skia context so that all the rendered stuff appears on the
767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // texture.
768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  offscreen_contexts->GrContext()->flush();
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flush the GL context so rendering results from this context are
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // visible in the compositor's context.
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  offscreen_contexts->ContextGL()->Flush();
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return device.accessBitmap(false);
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters(
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const RenderPassDrawQuad* quad,
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform& contents_device_transform,
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const gfx::Transform& contents_device_transform_inverse,
782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool* background_changed) {
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method draws a background filter, which applies a filter to any pixels
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // behind the quad and seen through its background.  The algorithm works as
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // follows:
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1. Compute a bounding box around the pixels that will be visible through
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the quad.
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2. Read the pixels in the bounding box into a buffer R.
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 3. Apply the background filter to R, so that it is applied in the pixels'
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // coordinate space.
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 4. Apply the quad's inverse transform to map the pixels in R into the
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad's content space. This implicitly clips R by the content bounds of the
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad since the destination texture has bounds matching the quad's content.
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 5. Draw the background texture for the contents using the same transform as
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to draw the contents itself. This is done without blending to replace
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the current background pixels with the new filtered background.
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 6. Draw the contents of the quad over drop of the new background with
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // blending, as per usual. The filtered background pixels will show through
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // any non-opaque pixels in this draws.
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): When this algorithm changes, update
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // LayerTreeHost::PrioritizeTextures() accordingly.
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): We only allow background filters on an opaque render surface
807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // because other surfaces may contain translucent pixels, and the contents
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // behind those translucent pixels wouldn't have the filter applied.
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool apply_background_filters =
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      !frame->current_render_pass->has_transparent_background;
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!frame->current_texture);
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(ajuma): Add support for reference filters once
8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // FilterOperations::GetOutsets supports reference filters.
815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (apply_background_filters && quad->background_filters.HasReferenceFilter())
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    apply_background_filters = false;
8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): Do a single readback for both the surface and replica and
819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // cache the filtered results (once filter textures are not reused).
8207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents_device_transform, SharedGeometryQuad().BoundingBox()));
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int top, right, bottom, left;
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  quad->background_filters.GetOutsets(&top, &right, &bottom, &left);
8257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  window_rect.Inset(-left, -top, -right, -bottom);
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  window_rect.Intersect(
8287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect));
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ScopedResource> device_background_texture =
831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ScopedResource::Create(resource_provider_);
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The TextureUsageFramebuffer hint makes ResourceProvider avoid immutable
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // storage allocation (texStorage2DEXT) for this texture. copyTexImage2D fails
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // when called on a texture having immutable storage.
835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  device_background_texture->Allocate(
836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      window_rect.size(), ResourceProvider::TextureUsageFramebuffer, RGBA_8888);
837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
8397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                             device_background_texture->id());
840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(
841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        lock.texture_id(), device_background_texture->format(), window_rect);
8427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      quad->background_filters, device_background_texture->size());
8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkBitmap filtered_device_background;
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (apply_background_filters) {
849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background =
850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ApplyImageFilter(this,
851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         frame->offscreen_context_provider,
852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         quad->rect.origin(),
853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         filter.get(),
854f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         device_background_texture.get());
855f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *background_changed = (filtered_device_background.getTexture() != NULL);
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
858f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int filtered_device_background_texture_id = 0;
859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (filtered_device_background.getTexture()) {
861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GrTexture* texture =
862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        reinterpret_cast<GrTexture*>(filtered_device_background.getTexture());
863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background_texture_id = texture->getTextureHandle();
864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    lock.reset(new ResourceProvider::ScopedReadLockGL(
866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        resource_provider_, device_background_texture->id()));
867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filtered_device_background_texture_id = lock->texture_id();
868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ScopedResource> background_texture =
871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ScopedResource::Create(resource_provider_);
872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  background_texture->Allocate(
873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      quad->rect.size(), ResourceProvider::TextureUsageFramebuffer, RGBA_8888);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const RenderPass* target_render_pass = frame->current_render_pass;
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool using_background_texture =
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UseScopedTexture(frame, background_texture.get(), quad->rect);
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (using_background_texture) {
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Copy the readback pixels from device to the background texture for the
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // surface.
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Transform device_to_framebuffer_transform;
8830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuadRectTransform(
8840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        &device_to_framebuffer_transform, gfx::Transform(), quad->rect);
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_to_framebuffer_transform.PreconcatTransform(
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents_device_transform_inverse);
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->Clear(GL_COLOR_BUFFER_BIT);
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The filtered_deveice_background_texture is oriented the same as the frame
8947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // buffer. The transform we are copying with has a vertical flip, as well as
8957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the |device_to_framebuffer_transform|, which cancel each other out. So do
8967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // not flip the contents in the shader to maintain orientation.
8977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool flip_vertically = false;
8987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CopyTextureToFramebuffer(frame,
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             filtered_device_background_texture_id,
9017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             window_rect,
9027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             device_to_framebuffer_transform,
9037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             flip_vertically);
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UseRenderPass(frame, target_render_pass);
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!using_background_texture)
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ScopedResource>();
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return background_texture.Pass();
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const RenderPassDrawQuad* quad) {
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedResource* contents_texture =
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_pass_textures_.get(quad->render_pass_id);
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents_texture || !contents_texture->id())
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform =
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_device_transform.FlattenTo2d();
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Can only draw surface if device matrix is invertible.
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform_inverse(
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Transform::kSkipInitialization);
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents_device_transform.GetInverse(&contents_device_transform_inverse))
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool need_background_texture =
935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode ||
936f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      !quad->background_filters.IsEmpty();
937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool background_changed = false;
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ScopedResource> background_texture;
939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (need_background_texture) {
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The pixels from the filtered background should completely replace the
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // current pixel values.
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool disable_blending = blend_enabled();
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (disable_blending)
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetBlendEnabled(false);
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    background_texture =
947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        GetBackgroundWithFilters(frame,
948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 quad,
949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 contents_device_transform,
950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 contents_device_transform_inverse,
951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 &background_changed);
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (disable_blending)
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetBlendEnabled(true);
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(senorblanco): Cache this value so that we don't have to do it for both
958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the surface and its replica.  Apply filters to the contents texture.
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap filter_bitmap;
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SkScalar color_matrix[20];
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_color_matrix = false;
96268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(ajuma): Always use RenderSurfaceFilters::BuildImageFilter, not just
96368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // when we have a reference filter.
9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!quad->filters.IsEmpty()) {
96568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
96668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        quad->filters, contents_texture->size());
96768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (filter) {
96868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      skia::RefPtr<SkColorFilter> cf;
96968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
97068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      {
97168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        SkColorFilter* colorfilter_rawptr = NULL;
97268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        filter->asColorFilter(&colorfilter_rawptr);
97368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        cf = skia::AdoptRef(colorfilter_rawptr);
97468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
97568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
97668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (cf && cf->asColorMatrix(color_matrix) && !filter->getInput(0)) {
97768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // We have a single color matrix as a filter; apply it locally
97868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // in the compositor.
97968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        use_color_matrix = true;
98068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      } else {
98168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        filter_bitmap = ApplyImageFilter(this,
98268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         frame->offscreen_context_provider,
98368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         quad->rect.origin(),
98468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         filter.get(),
98568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         contents_texture);
98668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode &&
991f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      background_texture) {
992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filter_bitmap =
993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ApplyBlendModeWithBackdrop(this,
994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   frame->offscreen_context_provider,
995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   filter_bitmap,
996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   contents_texture,
997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   background_texture.get(),
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   quad->shared_quad_state->blend_mode);
999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Draw the background texture if it has some filters applied.
1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (background_texture && background_changed) {
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(background_texture->size() == quad->rect.size());
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(resource_provider_,
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            background_texture->id());
10067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
10077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The background_texture is oriented the same as the frame buffer. The
10087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // transform we are copying with has a vertical flip, so flip the contents
10097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // in the shader to maintain orientation
10107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool flip_vertically = true;
10117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
10127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    CopyTextureToFramebuffer(frame,
10137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             lock.texture_id(),
10147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             quad->rect,
10157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             quad->quadTransform(),
10167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             flip_vertically);
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool clipped = false;
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF device_quad = MathUtil::MapQuad(
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents_device_transform, SharedGeometryQuad(), &clipped);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox()));
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_edges(device_quad);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use anti-aliasing programs only when necessary.
1026a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool use_aa =
1027a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      !clipped && (!device_quad.IsRectilinear() ||
1028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
1029a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                     kAntiAliasingEpsilon));
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_bounds.InflateAntiAliasingDistance();
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_edges.InflateAntiAliasingDistance();
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedReadLockGL> mask_resource_lock;
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned mask_texture_id = 0;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->mask_resource_id) {
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_resource_lock.reset(new ResourceProvider::ScopedReadLockGL(
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider_, quad->mask_resource_id));
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_texture_id = mask_resource_lock->texture_id();
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): use the background_texture and blend the background in with
1044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // this draw instead of having a separate copy of the background texture.
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (filter_bitmap.getTexture()) {
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GrTexture* texture =
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<GrTexture*>(filter_bitmap.getTexture());
1050a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
1051a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
1053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    contents_resource_lock =
1054a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        make_scoped_ptr(new ResourceProvider::ScopedSamplerGL(
1055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            resource_provider_, contents_texture->id(), GL_LINEAR));
1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              contents_resource_lock->target());
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1061a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1062a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_quad_location = -1;
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_edge_location = -1;
1068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int shader_viewport_location = -1;
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_sampler_location = -1;
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_tex_coord_scale_location = -1;
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_mask_tex_coord_offset_location = -1;
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_matrix_location = -1;
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_alpha_location = -1;
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int shader_color_matrix_location = -1;
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int shader_color_offset_location = -1;
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shader_tex_transform_location = -1;
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (use_aa && mask_texture_id && !use_color_matrix) {
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskProgramAA* program =
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskProgramAA(tex_coord_precision);
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1082a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1084b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
1085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_sampler_location =
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
10957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
10967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && mask_texture_id && !use_color_matrix) {
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskProgram* program =
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskProgram(tex_coord_precision);
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_sampler_location =
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_tex_transform_location =
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && !mask_texture_id && !use_color_matrix) {
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassProgramAA* program =
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassProgramAA(tex_coord_precision);
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
1120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
11247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && mask_texture_id && use_color_matrix) {
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskColorMatrixProgramAA* program =
1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision);
1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
11347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_sampler_location =
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
1145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (use_aa && !mask_texture_id && use_color_matrix) {
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassColorMatrixProgramAA* program =
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassColorMatrixProgramAA(tex_coord_precision);
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    shader_quad_location = program->vertex_shader().quad_location();
11577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    shader_tex_transform_location =
11587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        program->vertex_shader().tex_transform_location();
1159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_edge_location = program->vertex_shader().edge_location();
1160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    shader_viewport_location = program->vertex_shader().viewport_location();
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && mask_texture_id && use_color_matrix) {
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassMaskColorMatrixProgram* program =
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassMaskColorMatrixProgram(tex_coord_precision);
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_tex_transform_location =
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_sampler_location =
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_sampler_location();
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_scale_location =
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_scale_location();
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_mask_tex_coord_offset_location =
1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().mask_tex_coord_offset_location();
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!use_aa && !mask_texture_id && use_color_matrix) {
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassColorMatrixProgram* program =
1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassColorMatrixProgram(tex_coord_precision);
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetUseProgram(program->program());
1190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_tex_transform_location =
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_matrix_location =
1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_matrix_location();
1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shader_color_offset_location =
1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        program->fragment_shader().color_offset_location();
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RenderPassProgram* program =
1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRenderPassProgram(tex_coord_precision);
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetUseProgram(program->program());
1204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_matrix_location = program->vertex_shader().matrix_location();
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_alpha_location = program->fragment_shader().alpha_location();
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shader_tex_transform_location =
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().tex_transform_location();
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_x =
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      quad->rect.width() / static_cast<float>(contents_texture->size().width());
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float tex_scale_y = quad->rect.height() /
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      static_cast<float>(contents_texture->size().height());
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(tex_scale_x, 1.0f);
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(tex_scale_y, 1.0f);
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(shader_tex_transform_location != -1 || IsContextLost());
12197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Flip the content vertically in the shader, as the RenderPass input
12207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // texture is already oriented the same way as the framebuffer, but the
12217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // projection transform does a flip.
1222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(shader_tex_transform_location,
1224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     0.0f,
1225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_y,
1226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     tex_scale_x,
1227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     -tex_scale_y));
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_mask_sampler_lock;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shader_mask_sampler_location != -1) {
1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE(shader_mask_tex_coord_scale_location, 1);
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_NE(shader_mask_tex_coord_offset_location, 1);
1233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(shader_mask_sampler_location, 1));
12347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    float mask_tex_scale_x = quad->mask_uv_rect.width() / tex_scale_x;
12367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    float mask_tex_scale_y = quad->mask_uv_rect.height() / tex_scale_y;
12377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Mask textures are oriented vertically flipped relative to the framebuffer
12397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // and the RenderPass contents texture, so we flip the tex coords from the
12407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // RenderPass texture to find the mask texture coords.
1241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform2f(shader_mask_tex_coord_offset_location,
1243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->mask_uv_rect.x(),
1244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->mask_uv_rect.y() + quad->mask_uv_rect.height()));
1245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform2f(shader_mask_tex_coord_scale_location,
1247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       mask_tex_scale_x,
1248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       -mask_tex_scale_y));
1249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    shader_mask_sampler_lock = make_scoped_ptr(
1250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new ResourceProvider::ScopedSamplerGL(resource_provider_,
1251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              quad->mask_resource_id,
1252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              GL_TEXTURE1,
1253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              GL_LINEAR));
1254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
1255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              shader_mask_sampler_lock->target());
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shader_edge_location != -1) {
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float edge[24];
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_edges.ToFloatArray(edge);
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_layer_bounds.ToFloatArray(&edge[12]);
1262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(shader_edge_location, 8, edge));
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (shader_viewport_location != -1) {
1266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(shader_viewport_location, 1, viewport));
1271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shader_color_matrix_location != -1) {
1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    float matrix[16];
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int i = 0; i < 4; ++i) {
1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (int j = 0; j < 4; ++j)
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        matrix[i * 4 + j] = SkScalarToFloat(color_matrix[j * 5 + i]);
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->UniformMatrix4fv(shader_color_matrix_location, 1, false, matrix));
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const float kScale = 1.0f / 255.0f;
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shader_color_offset_location != -1) {
1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    float offset[4];
1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int i = 0; i < 4; ++i)
1286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      offset[i] = SkScalarToFloat(color_matrix[i * 5 + 4]) * kScale;
1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(shader_color_offset_location, 1, offset));
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map device space quad to surface space. contents_device_transform has no 3d
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // component since it was flattened, so we don't need to project.
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse,
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              device_layer_edges.ToQuadF(),
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              &clipped);
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(), shader_alpha_location);
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderQuadF(surface_quad, shader_quad_location);
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), quad->rect, shader_matrix_location);
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush the compositor context before the filter bitmap goes out of
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // scope, so the draw gets processed before the filter texture gets deleted.
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (filter_bitmap.getTexture())
1305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Flush());
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SolidColorProgramUniforms {
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program;
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned matrix_location;
1311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned viewport_location;
1312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned quad_location;
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned edge_location;
1314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned color_location;
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class T>
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void SolidColorUniformLocation(T program,
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      SolidColorProgramUniforms* uniforms) {
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->program = program->program();
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->matrix_location = program->vertex_shader().matrix_location();
1322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->viewport_location = program->vertex_shader().viewport_location();
1323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  uniforms->quad_location = program->vertex_shader().quad_location();
1324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->edge_location = program->vertex_shader().edge_location();
1325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->color_location = program->fragment_shader().color_location();
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::SetupQuadForAntialiasing(
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform& device_transform,
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DrawQuad* quad,
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::QuadF* local_quad,
133358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    float edge[24]) {
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool clipped = false;
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF device_layer_quad = MathUtil::MapQuad(
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_transform, gfx::QuadF(quad->visibleContentRect()), &clipped);
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_axis_aligned_in_target = device_layer_quad.IsRectilinear();
1341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool is_nearest_rect_within_epsilon =
1342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      is_axis_aligned_in_target &&
1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(),
1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       kAntiAliasingEpsilon);
134558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // AAing clipped quads is not supported by the code yet.
134658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool use_aa = !clipped && !is_nearest_rect_within_epsilon && quad->IsEdge();
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!use_aa)
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_bounds(gfx::QuadF(device_layer_quad.BoundingBox()));
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_bounds.InflateAntiAliasingDistance();
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_layer_edges(device_layer_quad);
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_edges.InflateAntiAliasingDistance();
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_edges.ToFloatArray(edge);
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_layer_bounds.ToFloatArray(&edge[12]);
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF bottom_right = tile_rect.bottom_right();
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF bottom_left = tile_rect.bottom_left();
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF top_left = tile_rect.origin();
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF top_right = tile_rect.top_right();
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map points to device space.
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_right = MathUtil::MapPoint(device_transform, bottom_right, &clipped);
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_left = MathUtil::MapPoint(device_transform, bottom_left, &clipped);
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_left = MathUtil::MapPoint(device_transform, top_left, &clipped);
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_right = MathUtil::MapPoint(device_transform, top_right, &clipped);
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!clipped);
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge bottom_edge(bottom_right, bottom_left);
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge left_edge(bottom_left, top_left);
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge top_edge(top_left, top_right);
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad::Edge right_edge(top_right, bottom_right);
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only apply anti-aliasing to edges not clipped by culling or scissoring.
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsTopEdge() && tile_rect.y() == quad->rect.y())
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    top_edge = device_layer_edges.top();
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsLeftEdge() && tile_rect.x() == quad->rect.x())
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    left_edge = device_layer_edges.left();
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsRightEdge() && tile_rect.right() == quad->rect.right())
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    right_edge = device_layer_edges.right();
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->IsBottomEdge() && tile_rect.bottom() == quad->rect.bottom())
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bottom_edge = device_layer_edges.bottom();
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float sign = gfx::QuadF(tile_rect).IsCounterClockwise() ? -1 : 1;
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bottom_edge.scale(sign);
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  left_edge.scale(sign);
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  top_edge.scale(sign);
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  right_edge.scale(sign);
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create device space quad.
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerQuad device_quad(left_edge, top_edge, right_edge, bottom_edge);
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map device space quad to local space. device_transform has no 3d
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // component since it was flattened, so we don't need to project.  We should
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have already checked that the transform was uninvertible above.
1401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool did_invert = device_transform.GetInverse(&inverse_device_transform);
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(did_invert);
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *local_quad = MathUtil::MapQuad(
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inverse_device_transform, device_quad.ToQuadF(), &clipped);
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not DCHECK(!clipped) here, because anti-aliasing inflation may
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // cause device_quad to become clipped. To our knowledge this scenario does
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not need to be handled differently than the unclipped case.
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const SolidColorDrawQuad* quad) {
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SkColor color = quad->color;
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  float opacity = quad->opacity();
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Early out if alpha is small enough that quad doesn't contribute to output.
1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (alpha < std::numeric_limits<float>::epsilon() &&
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->ShouldDrawWithBlending())
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform device_transform =
1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_transform.FlattenTo2d();
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_transform.IsInvertible())
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float edge[24];
143458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool use_aa =
143558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_->allow_antialiasing && !quad->force_anti_aliasing_off &&
143658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SolidColorProgramUniforms uniforms;
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa)
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SolidColorUniformLocation(GetSolidColorProgramAA(), &uniforms);
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SolidColorUniformLocation(GetSolidColorProgram(), &uniforms);
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(uniforms.program);
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4f(uniforms.color_location,
1447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
1448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
1449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
1450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     alpha));
1451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (use_aa) {
1452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
1457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
1458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable blending when the quad properties require it or if we decided
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to use antialiasing.
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normalize to tile_rect.
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetShaderQuadF(local_quad, uniforms.quad_location);
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transform and vertex data are used to figure out the extents that the
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // un-antialiased quad should have and which vertex this is and the float
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad passed in via uniform is the actual geometry that gets used to draw
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it. This is why this centered rect is used and not the original quad_rect.
1473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::RectF centered_rect(
1474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
1475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_rect.size());
1476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DrawQuadGeometry(
1477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TileProgramUniforms {
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program;
1482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned matrix_location;
1483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned viewport_location;
1484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned quad_location;
1485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned edge_location;
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned vertex_tex_transform_location;
1487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned sampler_location;
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned fragment_tex_transform_location;
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned alpha_location;
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T>
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void TileUniformLocation(T program, TileProgramUniforms* uniforms) {
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->program = program->program();
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->matrix_location = program->vertex_shader().matrix_location();
1496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->viewport_location = program->vertex_shader().viewport_location();
1497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  uniforms->quad_location = program->vertex_shader().quad_location();
1498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->edge_location = program->vertex_shader().edge_location();
1499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uniforms->vertex_tex_transform_location =
1500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      program->vertex_shader().vertex_tex_transform_location();
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->sampler_location = program->fragment_shader().sampler_location();
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->alpha_location = program->fragment_shader().alpha_location();
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uniforms->fragment_tex_transform_location =
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program->fragment_shader().fragment_tex_transform_location();
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawTileQuad(const DrawingFrame* frame,
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const TileDrawQuad* quad) {
1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawContentQuad(frame, quad, quad->resource_id);
1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawContentQuad(const DrawingFrame* frame,
1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const ContentDrawQuadBase* quad,
1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 ResourceProvider::ResourceId resource_id) {
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect tile_rect = quad->visible_rect;
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional(
1519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      quad->tex_coord_rect, quad->rect, tile_rect);
1520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  float tex_to_geom_scale_x = quad->rect.width() / quad->tex_coord_rect.width();
1521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  float tex_to_geom_scale_y =
1522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      quad->rect.height() / quad->tex_coord_rect.height();
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF clamp_geom_rect(tile_rect);
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF clamp_tex_rect(tex_coord_rect);
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clamp texture coordinates to avoid sampling outside the layer
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by deflating the tile region half a texel or half a texel
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // minus epsilon for one pixel layers. The resulting clamp region
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is mapped to the unit square by the vertex shader and mapped
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // back to normalized texture coordinates by the fragment shader
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after being clamped to 0-1 range.
1532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float tex_clamp_x =
1533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(0.5f, 0.5f * clamp_tex_rect.width() - kAntiAliasingEpsilon);
1534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float tex_clamp_y =
1535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(0.5f, 0.5f * clamp_tex_rect.height() - kAntiAliasingEpsilon);
1536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float geom_clamp_x =
1537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(tex_clamp_x * tex_to_geom_scale_x,
1538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               0.5f * clamp_geom_rect.width() - kAntiAliasingEpsilon);
1539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float geom_clamp_y =
1540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::min(tex_clamp_y * tex_to_geom_scale_y,
1541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               0.5f * clamp_geom_rect.height() - kAntiAliasingEpsilon);
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  clamp_geom_rect.Inset(geom_clamp_x, geom_clamp_y, geom_clamp_x, geom_clamp_y);
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  clamp_tex_rect.Inset(tex_clamp_x, tex_clamp_y, tex_clamp_x, tex_clamp_y);
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map clamping rectangle to unit square.
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_translate_x = -clamp_geom_rect.x() / clamp_geom_rect.width();
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_translate_y =
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      -clamp_geom_rect.y() / clamp_geom_rect.height();
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_scale_x = tile_rect.width() / clamp_geom_rect.width();
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float vertex_tex_scale_y = tile_rect.height() / clamp_geom_rect.height();
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_, &highp_threshold_cache_, highp_threshold_min_, quad->texture_size);
1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform device_transform =
1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_transform.FlattenTo2d();
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_transform.IsInvertible())
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float edge[24];
1563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool use_aa =
1564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      settings_->allow_antialiasing &&
1565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f);
1568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GLenum filter = (use_aa || scaled ||
1569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   !quad->quadTransform().IsIdentityOrIntegerTranslation())
1570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      ? GL_LINEAR
1571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      : GL_NEAREST;
1572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL quad_resource_lock(
1573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resource_provider_, resource_id, filter);
1574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SamplerType sampler =
1575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      SamplerTypeFromTextureTarget(quad_resource_lock.target());
1576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_translate_x = clamp_tex_rect.x();
1578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_translate_y = clamp_tex_rect.y();
1579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_scale_x = clamp_tex_rect.width();
1580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  float fragment_tex_scale_y = clamp_tex_rect.height();
1581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Map to normalized texture coordinates.
1583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sampler != SamplerType2DRect) {
1584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Size texture_size = quad->texture_size;
1585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!texture_size.IsEmpty());
1586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_translate_x /= texture_size.width();
1587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_translate_y /= texture_size.height();
1588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_scale_x /= texture_size.width();
1589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fragment_tex_scale_y /= texture_size.height();
1590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TileProgramUniforms uniforms;
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (quad->swizzle_contents) {
1595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      TileUniformLocation(GetTileProgramSwizzleAA(tex_coord_precision, sampler),
1596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          &uniforms);
1597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
1598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      TileUniformLocation(GetTileProgramAA(tex_coord_precision, sampler),
1599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          &uniforms);
1600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (quad->ShouldDrawWithBlending()) {
1603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (quad->swizzle_contents) {
1604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        TileUniformLocation(GetTileProgramSwizzle(tex_coord_precision, sampler),
1605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            &uniforms);
1606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
1607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(GetTileProgram(tex_coord_precision, sampler),
1608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &uniforms);
1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (quad->swizzle_contents) {
1612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(
1613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            GetTileProgramSwizzleOpaque(tex_coord_precision, sampler),
1614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            &uniforms);
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
1616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TileUniformLocation(GetTileProgramOpaque(tex_coord_precision, sampler),
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            &uniforms);
1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(uniforms.program);
1623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(uniforms.sampler_location, 0));
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_aa) {
1626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float viewport[4] = {static_cast<float>(viewport_.x()),
1627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.y()),
1628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.width()),
1629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         static_cast<float>(viewport_.height()), };
1630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
1631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
1632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.vertex_tex_transform_location,
1635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_x,
1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_y,
1637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_x,
1638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_y));
1639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.fragment_tex_transform_location,
1641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_translate_x,
1642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_translate_y,
1643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_scale_x,
1644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       fragment_tex_scale_y));
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move fragment shader transform to vertex shader. We can do this while
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // still producing correct results as fragment_tex_transform_location
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // should always be non-negative when tiles are transformed in a way
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // that could result in sampling outside the layer.
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_scale_x *= fragment_tex_scale_x;
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_scale_y *= fragment_tex_scale_y;
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_x *= fragment_tex_scale_x;
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_y *= fragment_tex_scale_y;
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_x += fragment_tex_translate_x;
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_tex_translate_y += fragment_tex_translate_y;
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(uniforms.vertex_tex_transform_location,
1659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_x,
1660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_translate_y,
1661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_x,
1662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       vertex_tex_scale_y));
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enable blending when the quad properties require it or if we decided
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to use antialiasing.
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normalize to tile_rect.
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
1673b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetShaderQuadF(local_quad, uniforms.quad_location);
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transform and vertex data are used to figure out the extents that the
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // un-antialiased quad should have and which vertex this is and the float
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // quad passed in via uniform is the actual geometry that gets used to draw
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it. This is why this centered rect is used and not the original quad_rect.
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF centered_rect(
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tile_rect.size());
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const YUVVideoDrawQuad* quad) {
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool use_alpha_plane = quad->a_plane_resource_id != 0;
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL y_plane_lock(
1699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->y_plane_resource_id, GL_TEXTURE1, GL_LINEAR);
1700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), y_plane_lock.target());
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL u_plane_lock(
1702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->u_plane_resource_id, GL_TEXTURE2, GL_LINEAR);
1703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), u_plane_lock.target());
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedSamplerGL v_plane_lock(
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_provider_, quad->v_plane_resource_id, GL_TEXTURE3, GL_LINEAR);
1706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), v_plane_lock.target());
1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
1708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane) {
1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
1710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        resource_provider_, quad->a_plane_resource_id, GL_TEXTURE4, GL_LINEAR));
1711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), a_plane_lock->target());
1712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int matrix_location = -1;
1715effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int tex_scale_location = -1;
1716effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int tex_offset_location = -1;
1717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int y_texture_location = -1;
1718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int u_texture_location = -1;
1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int v_texture_location = -1;
1720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int a_texture_location = -1;
1721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int yuv_matrix_location = -1;
1722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int yuv_adj_location = -1;
1723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int alpha_location = -1;
1724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane) {
1725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const VideoYUVAProgram* program = GetVideoYUVAProgram(tex_coord_precision);
1726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(program && (program->initialized() || IsContextLost()));
1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SetUseProgram(program->program());
1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
1729effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_scale_location = program->vertex_shader().tex_scale_location();
1730effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_offset_location = program->vertex_shader().tex_offset_location();
1731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    y_texture_location = program->fragment_shader().y_texture_location();
1732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    u_texture_location = program->fragment_shader().u_texture_location();
1733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v_texture_location = program->fragment_shader().v_texture_location();
1734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    a_texture_location = program->fragment_shader().a_texture_location();
1735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
1736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_adj_location = program->fragment_shader().yuv_adj_location();
1737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    alpha_location = program->fragment_shader().alpha_location();
1738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
1739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision);
1740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(program && (program->initialized() || IsContextLost()));
1741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SetUseProgram(program->program());
1742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
1743effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_scale_location = program->vertex_shader().tex_scale_location();
1744effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    tex_offset_location = program->vertex_shader().tex_offset_location();
1745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    y_texture_location = program->fragment_shader().y_texture_location();
1746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    u_texture_location = program->fragment_shader().u_texture_location();
1747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v_texture_location = program->fragment_shader().v_texture_location();
1748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
1749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    yuv_adj_location = program->fragment_shader().yuv_adj_location();
1750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    alpha_location = program->fragment_shader().alpha_location();
1751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform2f(tex_scale_location,
1755effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.width(),
1756effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.height()));
1757effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  GLC(gl_,
1758effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      gl_->Uniform2f(tex_offset_location,
1759effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.x(),
1760effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     quad->tex_coord_rect.y()));
1761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(y_texture_location, 1));
1762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(u_texture_location, 2));
1763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(v_texture_location, 3));
1764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_alpha_plane)
1765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1i(a_texture_location, 4));
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These values are magic numbers that are used in the transformation from YUV
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to RGB color values.  They are taken from the following webpage:
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.fourcc.org/fccyvrgb.php
1770a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float yuv_to_rgb[9] = {1.164f, 1.164f, 1.164f, 0.0f, -.391f,
1771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         2.018f, 1.596f, -.813f, 0.0f, };
1772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These values map to 16, 128, and 128 respectively, and are computed
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // They are used in the YUV to RGBA conversion formula:
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   Y - 16   : Gives 16 values of head and footroom for overshooting
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   U - 128  : Turns unsigned U into signed U [-128,127]
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   V - 128  : Turns unsigned V into signed V [-128,127]
1780a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  float yuv_adjust[3] = {-0.0625f, -0.5f, -0.5f, };
1781a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust));
1782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetShaderOpacity(quad->opacity(), alpha_location);
1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DrawQuadGeometry(frame, quad->quadTransform(), quad->rect, matrix_location);
17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const StreamVideoDrawQuad* quad) {
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(capabilities_.using_egl_image);
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1796a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1797a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
1800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoStreamTextureProgram* program =
1802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetVideoStreamTextureProgram(tex_coord_precision);
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(program->program());
18042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ToGLMatrix(&gl_matrix[0], quad->matrix);
1806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          program->vertex_shader().tex_matrix_location(), 1, false, gl_matrix));
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
1811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          quad->resource_id);
1812a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
1813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id()));
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetShaderOpacity(quad->opacity(),
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->fragment_shader().alpha_location());
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(frame,
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->quadTransform(),
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   quad->rect,
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   program->vertex_shader().matrix_location());
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawPictureQuad(const DrawingFrame* frame,
1826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const PictureDrawQuad* quad) {
1827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (on_demand_tile_raster_bitmap_.width() != quad->texture_size.width() ||
1828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      on_demand_tile_raster_bitmap_.height() != quad->texture_size.height()) {
1829effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    on_demand_tile_raster_bitmap_.allocN32Pixels(quad->texture_size.width(),
1830effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                 quad->texture_size.height());
1831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (on_demand_tile_raster_resource_id_)
1833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
1834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    on_demand_tile_raster_resource_id_ =
1836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        resource_provider_->CreateGLTexture(quad->texture_size,
1837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            GL_TEXTURE_2D,
1838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
1839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            GL_CLAMP_TO_EDGE,
1840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            ResourceProvider::TextureUsageAny,
1841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            quad->texture_format);
1842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create and run on-demand raster task for tile.
1845a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<Task> on_demand_raster_task(
18465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new OnDemandRasterTaskImpl(quad->picture_pile,
18475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 &on_demand_tile_raster_bitmap_,
18485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 quad->content_rect,
18495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 quad->contents_scale));
18505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunOnDemandRasterTask(on_demand_raster_task.get());
1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1852d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint8_t* bitmap_pixels = NULL;
1853d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SkBitmap on_demand_tile_raster_bitmap_dest;
1854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SkColorType colorType = ResourceFormatToSkColorType(quad->texture_format);
1855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (on_demand_tile_raster_bitmap_.colorType() != colorType) {
1856d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    on_demand_tile_raster_bitmap_.copyTo(&on_demand_tile_raster_bitmap_dest,
1857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         colorType);
1858d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
1859d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // bitmap data. This check will be removed once crbug.com/293728 is fixed.
1860d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CHECK_EQ(0u, on_demand_tile_raster_bitmap_dest.rowBytes() % 4);
1861d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bitmap_pixels = reinterpret_cast<uint8_t*>(
1862d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        on_demand_tile_raster_bitmap_dest.getPixels());
1863d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
1864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bitmap_pixels =
1865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        reinterpret_cast<uint8_t*>(on_demand_tile_raster_bitmap_.getPixels());
1866d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
1867d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  resource_provider_->SetPixels(on_demand_tile_raster_resource_id_,
1869a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                bitmap_pixels,
1870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Rect(quad->texture_size),
1871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Rect(quad->texture_size),
1872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                gfx::Vector2d());
1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawContentQuad(frame, quad, on_demand_tile_raster_resource_id_);
1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TextureProgramBinding {
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class Program>
1879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Set(Program* program) {
1880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(program);
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_id = program->program();
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sampler_location = program->fragment_shader().sampler_location();
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    matrix_location = program->vertex_shader().matrix_location();
18847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    background_color_location =
18857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        program->fragment_shader().background_color_location();
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int program_id;
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int sampler_location;
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int matrix_location;
18907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int background_color_location;
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TexTransformTextureProgramBinding : TextureProgramBinding {
18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class Program>
1895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Set(Program* program) {
1896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TextureProgramBinding::Set(program);
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tex_transform_location = program->vertex_shader().tex_transform_location();
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_opacity_location =
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->vertex_shader().vertex_opacity_location();
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int tex_transform_location;
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int vertex_opacity_location;
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::FlushTextureQuadCache() {
19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check to see if we have anything to draw.
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_cache_.program_id == 0)
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the correct blending mode.
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(draw_cache_.needs_blending);
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind the program to the GL state.
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(draw_cache_.program_id);
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind the correct texture sampler location.
1917a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(draw_cache_.sampler_location, 0));
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Assume the current active textures is 0.
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL locked_quad(resource_provider_,
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 draw_cache_.resource_id);
1922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
1923a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, locked_quad.texture_id()));
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float),  // NOLINT(runtime/sizeof)
1926a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 struct_is_densely_packed);
1927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  COMPILE_ASSERT(
1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sizeof(Float16) == 16 * sizeof(float),  // NOLINT(runtime/sizeof)
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      struct_is_densely_packed);
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Upload the tranforms for both points and uvs.
1932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->UniformMatrix4fv(
19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.matrix_location),
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.matrix_data.size()),
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          false,
19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<float*>(&draw_cache_.matrix_data.front())));
1938a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1939a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform4fv(
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.uv_xform_location),
19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.uv_xform_data.size()),
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<float*>(&draw_cache_.uv_xform_data.front())));
19437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
19447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (draw_cache_.background_color != SK_ColorTRANSPARENT) {
19457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Float4 background_color = PremultipliedColor(draw_cache_.background_color);
1946a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
1947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4fv(
19487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            draw_cache_.background_color_location, 1, background_color.data));
19497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
19507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Uniform1fv(
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.vertex_opacity_location),
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<int>(draw_cache_.vertex_opacity_data.size()),
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<float*>(&draw_cache_.vertex_opacity_data.front())));
19562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw the quads!
1958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
1959a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->DrawElements(GL_TRIANGLES,
1960a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        6 * draw_cache_.matrix_data.size(),
1961a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        GL_UNSIGNED_SHORT,
1962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        0));
19632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear the cache.
19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.program_id = 0;
19662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.uv_xform_data.resize(0);
19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.resize(0);
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.matrix_data.resize(0);
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const TextureDrawQuad* quad) {
1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
1974a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
1975a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
1976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
1977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
1978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Choose the correct texture program binding
19802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TexTransformTextureProgramBinding binding;
1981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (quad->premultiplied_alpha) {
19827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (quad->background_color == SK_ColorTRANSPARENT) {
1983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetTextureProgram(tex_coord_precision));
19847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
1985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetTextureBackgroundProgram(tex_coord_precision));
19867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
1987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
19887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (quad->background_color == SK_ColorTRANSPARENT) {
1989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      binding.Set(GetNonPremultipliedTextureProgram(tex_coord_precision));
19907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
19917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      binding.Set(
1992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          GetNonPremultipliedTextureBackgroundProgram(tex_coord_precision));
19937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
1994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resource_id = quad->resource_id;
19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_cache_.program_id != binding.program_id ||
19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.resource_id != resource_id ||
20002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.needs_blending != quad->ShouldDrawWithBlending() ||
20017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      draw_cache_.background_color != quad->background_color ||
20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_cache_.matrix_data.size() >= 8) {
20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FlushTextureQuadCache();
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.program_id = binding.program_id;
20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.resource_id = resource_id;
20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.needs_blending = quad->ShouldDrawWithBlending();
20077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    draw_cache_.background_color = quad->background_color;
20082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.uv_xform_location = binding.tex_transform_location;
20107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    draw_cache_.background_color_location = binding.background_color_location;
20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.vertex_opacity_location = binding.vertex_opacity_location;
20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.matrix_location = binding.matrix_location;
20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_cache_.sampler_location = binding.sampler_location;
20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the uv-transform
2017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  draw_cache_.uv_xform_data.push_back(UVTransform(quad));
20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the vertex opacity
20202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const float opacity = quad->opacity();
20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity);
20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity);
20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity);
20242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[3] * opacity);
20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate the transform matrix
20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
2029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  quad_rect_matrix = frame->projection_matrix * quad_rect_matrix;
20302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Float16 m;
20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  quad_rect_matrix.matrix().asColMajorf(m.data);
20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draw_cache_.matrix_data.push_back(m);
20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
20372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const IOSurfaceDrawQuad* quad) {
20382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetBlendEnabled(quad->ShouldDrawWithBlending());
20392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_,
2042a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &highp_threshold_cache_,
2043a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      highp_threshold_min_,
2044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quad->shared_quad_state->visible_content_rect.bottom_right());
2045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TexTransformTextureProgramBinding binding;
2047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  binding.Set(GetTextureIOSurfaceProgram(tex_coord_precision));
20482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUseProgram(binding.program_id);
2050a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(binding.sampler_location, 0));
20512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) {
2052a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(binding.tex_transform_location,
2054a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height(),
2056a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.width(),
2057a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height() * -1.0f));
20582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2059a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2060a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(binding.tex_transform_location,
2061a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2062a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0,
2063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.width(),
2064a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       quad->io_surface_size.height()));
20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2067a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const float vertex_opacity[] = {quad->opacity(), quad->opacity(),
2068a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  quad->opacity(), quad->opacity()};
2069a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1fv(binding.vertex_opacity_location, 4, vertex_opacity));
20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
2072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          quad->io_surface_resource_id);
2073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
2074a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id()));
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, quad->quadTransform(), quad->rect, binding.matrix_location);
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2079a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0));
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) {
20830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (use_sync_query_) {
20840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(current_sync_query_);
20850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    current_sync_query_->End();
20860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_sync_queries_.push_back(current_sync_query_.Pass());
20870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
20880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
2090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  swap_buffer_rect_.Union(gfx::ToEnclosingRect(frame->root_damage_rect));
20912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_BLEND));
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  blend_shadow_ = false;
2094effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2095effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ScheduleOverlays(frame);
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); }
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::FlippedFramebuffer() const { return true; }
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureScissorTestEnabled() {
21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_scissor_enabled_)
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureScissorTestDisabled() {
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_scissor_enabled_)
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = false;
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::CopyCurrentRenderPassToBitmap(
2121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
212290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
2123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::Rect copy_rect = frame->current_render_pass->output_rect;
2124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (request->has_area())
2125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    copy_rect.Intersect(request->area());
2126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetFramebufferPixelsAsync(copy_rect, request.Pass());
2127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) {
21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.matrix().asColMajorf(gl_matrix);
21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) {
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad_location == -1)
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  float gl_quad[8];
2138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[0] = quad.p1().x();
2139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[1] = quad.p1().y();
2140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[2] = quad.p2().x();
2141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[3] = quad.p2().y();
2142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[4] = quad.p3().x();
2143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[5] = quad.p3().y();
2144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[6] = quad.p4().x();
2145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_quad[7] = quad.p4().y();
2146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform2fv(quad_location, 4, gl_quad));
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetShaderOpacity(float opacity, int alpha_location) {
21502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alpha_location != -1)
2151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Uniform1f(alpha_location, opacity));
21522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2154fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid GLRenderer::SetStencilEnabled(bool enabled) {
2155fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  if (enabled == stencil_shadow_)
2156fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    return;
2157fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
2158fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  if (enabled)
2159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
2160fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  else
2161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
2162fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  stencil_shadow_ = enabled;
2163fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
2164fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
21652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetBlendEnabled(bool enabled) {
21662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled == blend_shadow_)
21672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled)
2170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Enable(GL_BLEND));
21712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
2172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Disable(GL_BLEND));
21732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  blend_shadow_ = enabled;
21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::SetUseProgram(unsigned program) {
21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (program == program_shadow_)
21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->UseProgram(program);
21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program_shadow_ = program;
21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DrawQuadGeometry(const DrawingFrame* frame,
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Transform& draw_transform,
21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::RectF& quad_rect,
21862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  int matrix_location) {
21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
21882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, draw_transform, quad_rect);
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float gl_matrix[16];
2190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad_rect_matrix);
2191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->UniformMatrix4fv(matrix_location, 1, false, &gl_matrix[0]));
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame,
21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          int texture_id,
21985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const gfx::Rect& rect,
21997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                          const gfx::Transform& draw_matrix,
22007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                          bool flip_vertically) {
2201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
22037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const RenderPassProgram* program = GetRenderPassProgram(tex_coord_precision);
22057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetUseProgram(program->program());
22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (flip_vertically) {
2210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
2212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       -1.f));
22167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
2217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
2219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       0.f,
2221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f,
2222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       1.f));
22237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
22247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetShaderOpacity(1.f, program->fragment_shader().alpha_location());
2226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
2227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
22282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawQuadGeometry(
22292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame, draw_matrix, rect, program->vertex_shader().matrix_location());
22302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::Finish() {
22338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::Finish");
2234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Finish());
22352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
22382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!is_backbuffer_discarded_);
22392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc,benchmark", "GLRenderer::SwapBuffers");
22412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We're done! Time to swapbuffers!
22422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Size surface_size = output_surface_->SurfaceSize();
2244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
22455e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  CompositorFrame compositor_frame;
2246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  compositor_frame.metadata = metadata;
22475e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  compositor_frame.gl_frame_data = make_scoped_ptr(new GLFrameData);
2248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  compositor_frame.gl_frame_data->size = surface_size;
224958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (capabilities_.using_partial_swap) {
22502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If supported, we can save significant bandwidth by only swapping the
2251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // damaged/scissored region (clamped to the viewport).
2252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    swap_buffer_rect_.Intersect(gfx::Rect(surface_size));
2253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int flipped_y_pos_of_rect_bottom = surface_size.height() -
2254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       swap_buffer_rect_.y() -
2255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       swap_buffer_rect_.height();
22565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    compositor_frame.gl_frame_data->sub_buffer_rect =
22575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)        gfx::Rect(swap_buffer_rect_.x(),
22585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  flipped_y_pos_of_rect_bottom,
22595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  swap_buffer_rect_.width(),
22605e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                  swap_buffer_rect_.height());
22612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
22625e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    compositor_frame.gl_frame_data->sub_buffer_rect =
22635e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)        gfx::Rect(output_surface_->SurfaceSize());
22642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22655e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  output_surface_->SwapBuffers(&compositor_frame);
22662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Release previously used overlay resources and hold onto the pending ones
2268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // until the next swap buffers.
2269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.clear();
2270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  in_use_overlay_resources_.swap(pending_overlay_resources_);
2271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
22722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  swap_buffer_rect_ = gfx::Rect();
22732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnforceMemoryPolicy() {
22762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!visible_) {
22772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::EnforceMemoryPolicy dropping resources");
22782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReleaseRenderPassTextures();
22790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DiscardBackbuffer();
22802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->ReleaseCachedData();
2281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->Flush());
22822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::DiscardBackbuffer() {
22862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_backbuffer_discarded_)
22872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
22882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->DiscardBackbuffer();
22902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_backbuffer_discarded_ = true;
22922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Damage tracker needs a full reset every time framebuffer is discarded.
22942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->SetFullRootLayerDamage();
22952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::EnsureBackbuffer() {
22982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_backbuffer_discarded_)
22992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
23002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->EnsureBackbuffer();
23022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_backbuffer_discarded_ = false;
23032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GLRenderer::GetFramebufferPixels(void* pixels, const gfx::Rect& rect) {
2306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!pixels || rect.IsEmpty())
2307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // This function assumes that it is reading the root frame buffer.
2310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(!current_framebuffer_lock_);
2311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
2313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    pending_read.Pass());
2315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This is a syncronous call since the callback is null.
23177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
2318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DoGetFramebufferPixels(static_cast<uint8*>(pixels),
23197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         window_rect,
2320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         AsyncGetFramebufferPixelsCleanupCallback());
2321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
232390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GLRenderer::GetFramebufferPixelsAsync(
23245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& rect,
2325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
232690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!request->IsEmpty());
232790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (request->IsEmpty())
2328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
232990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (rect.IsEmpty())
2330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect);
23337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
23347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!request->force_bitmap_result()) {
2335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool own_mailbox = !request->has_texture_mailbox();
2336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint texture_id = 0;
2338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenTextures(1, &texture_id);
23397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
23407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gpu::Mailbox mailbox;
2341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (own_mailbox) {
2342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->GenMailboxCHROMIUM(mailbox.name));
2343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
23445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mailbox = request->texture_mailbox().mailbox();
2345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DCHECK_EQ(static_cast<unsigned>(GL_TEXTURE_2D),
2346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                request->texture_mailbox().target());
2347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DCHECK(!mailbox.IsZero());
2348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      unsigned incoming_sync_point = request->texture_mailbox().sync_point();
2349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (incoming_sync_point)
2350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GLC(gl_, gl_->WaitSyncPointCHROMIUM(incoming_sync_point));
2351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
2352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
2354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (own_mailbox) {
2355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(
2361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
2362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->TexParameteri(
2364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
2365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
2366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
2367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
23687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(texture_id, RGBA_8888, window_rect);
2370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
23717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    unsigned sync_point = gl_->InsertSyncPointCHROMIUM();
2373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureMailbox texture_mailbox(mailbox, GL_TEXTURE_2D, sync_point);
2374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback;
2376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (own_mailbox) {
2377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      release_callback = texture_mailbox_deleter_->GetReleaseCallback(
2378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          output_surface_->context_provider(), texture_id);
2379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
2380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->DeleteTextures(1, &texture_id);
2381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
2382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    request->SendTextureResult(
2384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        window_rect.size(), texture_mailbox, release_callback.Pass());
23857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
23867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
23877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
23887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(request->force_bitmap_result());
23897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
2391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bitmap->allocN32Pixels(window_rect.width(), window_rect.height());
2392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
2394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Save a pointer to the pixels, the bitmap is owned by the cleanup_callback.
2396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
2397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AsyncGetFramebufferPixelsCleanupCallback cleanup_callback =
2399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&GLRenderer::PassOnSkBitmap,
2400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 base::Unretained(this),
2401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 base::Passed(&bitmap),
2402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 base::Passed(&lock));
2403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
240590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pending_read->copy_request = request.Pass();
2406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    pending_read.Pass());
2408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This is an asyncronous call since the callback is not null.
24107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DoGetFramebufferPixels(pixels, window_rect, cleanup_callback);
2411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::DoGetFramebufferPixels(
2414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8* dest_pixels,
24155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& window_rect,
2416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) {
24177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.x(), 0);
24187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.y(), 0);
2419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_LE(window_rect.right(), current_surface_size_.width());
2420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
24212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool is_async = !cleanup_callback.is_null();
24232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool do_workaround = NeedsIOSurfaceReadbackWorkaround();
24252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned temporary_texture = 0;
2427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned temporary_fbo = 0;
24282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (do_workaround) {
24302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Mac OS X, calling glReadPixels() against an FBO whose color attachment
24312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is an IOSurface-backed texture causes corruption of future glReadPixels()
24322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // calls, even those on different OpenGL contexts. It is believed that this
24332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is the root cause of top crasher
24342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // http://crbug.com/99393. <rdar://problem/10949687>
24352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenTextures(1, &temporary_texture);
2437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, temporary_texture));
2438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
2444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
24462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Copy the contents of the current (IOSurface-backed) framebuffer into a
24472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // temporary texture.
2448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetFramebufferTexture(
2449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        temporary_texture, RGBA_8888, gfx::Rect(current_surface_size_));
2450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenFramebuffers(1, &temporary_fbo);
24512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attach this texture to an FBO, and perform the readback from that FBO.
2452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, temporary_fbo));
2453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
2455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  GL_COLOR_ATTACHMENT0,
2456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  GL_TEXTURE_2D,
2457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  temporary_texture,
2458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  0));
24597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
24607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
2461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              gl_->CheckFramebufferStatus(GL_FRAMEBUFFER));
24622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
24632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint buffer = 0;
2465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl_->GenBuffers(1, &buffer);
2466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, buffer));
2467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      4 * window_rect.size().GetArea(),
2470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      NULL,
2471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_STREAM_READ));
2472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint query = 0;
2474a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (is_async) {
2475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->GenQueriesEXT(1, &query);
2476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, query));
2477a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
2478a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->ReadPixels(window_rect.x(),
2481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.y(),
2482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.width(),
2483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      window_rect.height(),
2484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_RGBA,
2485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      GL_UNSIGNED_BYTE,
2486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      NULL));
2487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
24892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (do_workaround) {
24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clean up.
2492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
2493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
2494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteFramebuffers(1, &temporary_fbo));
2495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteTextures(1, &temporary_texture));
2496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Closure finished_callback = base::Bind(&GLRenderer::FinishedReadback,
2499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               base::Unretained(this),
2500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               cleanup_callback,
2501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               buffer,
2502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               query,
2503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               dest_pixels,
2504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               window_rect.size());
2505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Save the finished_callback so it can be cancelled.
2506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset(
2507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      finished_callback);
25085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Closure cancelable_callback =
25095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pending_async_read_pixels_.front()->
25105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          finished_read_pixels_callback.callback();
2511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Save the buffer to verify the callbacks happen in the expected order.
2513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.front()->buffer = buffer;
2514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_async) {
2516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM));
25175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_support_->SignalQuery(query, cancelable_callback);
2518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
2519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider_->Finish();
2520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    finished_callback.Run();
2521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnforceMemoryPolicy();
25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::FinishedReadback(
2527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback,
2528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned source_buffer,
2529a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    unsigned query,
2530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8* dest_pixels,
25315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size) {
2532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!pending_async_read_pixels_.empty());
253390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2534a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (query != 0) {
2535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteQueriesEXT(1, &query));
2536a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
2537a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
253890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back();
253990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure we service the readbacks in order.
254090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(source_buffer, current_read->buffer);
2541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8* src_pixels = NULL;
2543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (source_buffer != 0) {
2545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_,
2546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, source_buffer));
2547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    src_pixels = static_cast<uint8*>(gl_->MapBufferCHROMIUM(
2548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
2549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (src_pixels) {
2551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t row_bytes = size.width() * 4;
2552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int num_rows = size.height();
2553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t total_bytes = num_rows * row_bytes;
2554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
2555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Flip Y axis.
25567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        size_t src_y = total_bytes - dest_y - row_bytes;
2557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // Swizzle OpenGL -> Skia byte order.
2558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        for (size_t x = 0; x < row_bytes; x += 4) {
2559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_R32_SHIFT / 8] =
2560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 0];
2561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_G32_SHIFT / 8] =
2562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 1];
2563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_B32_SHIFT / 8] =
2564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 2];
2565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          dest_pixels[dest_y + x + SK_A32_SHIFT / 8] =
2566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              src_pixels[src_y + x + 3];
2567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
2568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
2569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_,
2571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM));
2572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
2574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteBuffers(1, &source_buffer));
2575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(danakj): This can go away when synchronous readback is no more and its
2578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // contents can just move here.
2579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!cleanup_callback.is_null())
258090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    cleanup_callback.Run(current_read->copy_request.Pass(), src_pixels != NULL);
2581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pending_async_read_pixels_.pop_back();
2583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::PassOnSkBitmap(scoped_ptr<SkBitmap> bitmap,
2586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                scoped_ptr<SkAutoLockPixels> lock,
2587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                scoped_ptr<CopyOutputRequest> request,
2588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                bool success) {
25897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(request->force_bitmap_result());
2590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  lock.reset();
2592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (success)
259390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    request->SendBitmapResult(bitmap.Pass());
2594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::GetFramebufferTexture(unsigned texture_id,
2597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       ResourceFormat texture_format,
25985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const gfx::Rect& window_rect) {
25997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(texture_id);
26007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.x(), 0);
26017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GE(window_rect.y(), 0);
26027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(window_rect.right(), current_surface_size_.width());
26037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
2606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->CopyTexImage2D(GL_TEXTURE_2D,
2608a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          0,
2609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLDataFormat(texture_format),
2610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.x(),
2611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.y(),
2612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.width(),
2613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          window_rect.height(),
2614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          0));
2615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
26162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool GLRenderer::UseScopedTexture(DrawingFrame* frame,
26192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const ScopedResource* texture,
26205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const gfx::Rect& viewport_rect) {
26212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture->id());
2622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  frame->current_render_pass = NULL;
2623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  frame->current_texture = texture;
26242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return BindFramebufferToTexture(frame, texture, viewport_rect);
26262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
26292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
26302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_surface_->BindFramebuffer();
2631fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
263258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (output_surface_->HasExternalStencilTest()) {
2633fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    SetStencilEnabled(true);
2634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->StencilFunc(GL_EQUAL, 1, 1));
2635fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  } else {
2636fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    SetStencilEnabled(false);
2637fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const ScopedResource* texture,
26425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const gfx::Rect& target_rect) {
26432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture->id());
26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2645b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_framebuffer_lock_.reset();
2646b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2647fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SetStencilEnabled(false);
2648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_));
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_ =
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL(
26512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_provider_, texture->id()));
26522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned texture_id = current_framebuffer_lock_->texture_id();
2653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->FramebufferTexture2D(
26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0));
26562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
2658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             GL_FRAMEBUFFER_COMPLETE ||
2659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         IsContextLost());
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeViewport(
2662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      frame, target_rect, gfx::Rect(target_rect.size()), target_rect.size());
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
26642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
26672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnsureScissorTestEnabled();
26682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't unnecessarily ask the context to change the scissor, because it
26702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // may cause undesired GPU pipeline flushes.
2671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (scissor_rect == scissor_rect_ && !scissor_rect_needs_reset_)
26722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
26732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scissor_rect_ = scissor_rect;
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushTextureQuadCache();
2676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Scissor(scissor_rect.x(),
2678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.y(),
2679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.width(),
2680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   scissor_rect.height()));
2681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scissor_rect_needs_reset_ = false;
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GLRenderer::SetDrawViewport(const gfx::Rect& window_space_viewport) {
2686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  viewport_ = window_space_viewport;
2687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_,
2688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->Viewport(window_space_viewport.x(),
2689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.y(),
2690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.width(),
2691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    window_space_viewport.height()));
26922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GLRenderer::InitializeSharedObjects() {
26952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects");
26962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create an FBO for doing offscreen rendering.
2698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->GenFramebuffers(1, &offscreen_framebuffer_id_));
26992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  shared_geometry_ = make_scoped_ptr(
2701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new GeometryBinding(gl_, QuadVertexRect()));
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::TileCheckerboardProgram*
27052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLRenderer::GetTileCheckerboardProgram() {
2706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!tile_checkerboard_program_.initialized()) {
27072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::checkerboardProgram::initalize");
2708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    tile_checkerboard_program_.Initialize(output_surface_->context_provider(),
2709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          TexCoordPrecisionNA,
2710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          SamplerTypeNA);
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &tile_checkerboard_program_;
27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::DebugBorderProgram* GLRenderer::GetDebugBorderProgram() {
2716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!debug_border_program_.initialized()) {
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::debugBorderProgram::initialize");
2718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    debug_border_program_.Initialize(output_surface_->context_provider(),
2719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     TexCoordPrecisionNA,
2720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     SamplerTypeNA);
27212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &debug_border_program_;
27232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::SolidColorProgram* GLRenderer::GetSolidColorProgram() {
2726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!solid_color_program_.initialized()) {
27272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::solidColorProgram::initialize");
2728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    solid_color_program_.Initialize(output_surface_->context_provider(),
2729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    TexCoordPrecisionNA,
2730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    SamplerTypeNA);
27312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &solid_color_program_;
27332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() {
2736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!solid_color_program_aa_.initialized()) {
27372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::solidColorProgramAA::initialize");
2738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    solid_color_program_aa_.Initialize(output_surface_->context_provider(),
2739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       TexCoordPrecisionNA,
2740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       SamplerTypeNA);
27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return &solid_color_program_aa_;
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram(
2746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassProgram* program = &render_pass_program_[precision];
2750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize");
2752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA(
2759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassProgramAA* program = &render_pass_program_aa_[precision];
2763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize");
2765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
27692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const GLRenderer::RenderPassMaskProgram* GLRenderer::GetRenderPassMaskProgram(
2772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
2773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskProgram* program = &render_pass_mask_program_[precision];
2776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize");
2778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
27802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
27822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::RenderPassMaskProgramAA*
2785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision) {
2786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskProgramAA* program = &render_pass_mask_program_aa_[precision];
2789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
27902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize");
2791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassColorMatrixProgram*
2798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision) {
2799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassColorMatrixProgram* program =
2802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_color_matrix_program_[precision];
2803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
2805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassColorMatrixProgramAA*
2812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
2813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassColorMatrixProgramAA* program =
2816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_color_matrix_program_aa_[precision];
2817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassColorMatrixProgramAA::initialize");
2820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassMaskColorMatrixProgram*
2827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
2828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskColorMatrixProgram* program =
2831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_mask_color_matrix_program_[precision];
2832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
2835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
2837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
2839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::RenderPassMaskColorMatrixProgramAA*
2842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
2843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderPassMaskColorMatrixProgramAA* program =
2846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &render_pass_mask_color_matrix_program_aa_[precision];
2847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("cc",
2849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
2850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgram* GLRenderer::GetTileProgram(
2857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgram* program = &tile_program_[precision][sampler];
2864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
28652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgram::initialize");
2866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
28682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramOpaque* GLRenderer::GetTileProgramOpaque(
2873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramOpaque* program = &tile_program_opaque_[precision][sampler];
2880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
28812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramOpaque::initialize");
2882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
28842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
28862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramAA* GLRenderer::GetTileProgramAA(
2889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramAA* program = &tile_program_aa_[precision][sampler];
2896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramAA::initialize");
2898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramSwizzle* GLRenderer::GetTileProgramSwizzle(
2905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramSwizzle* program = &tile_program_swizzle_[precision][sampler];
2912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzle::initialize");
2914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::TileProgramSwizzleOpaque*
2921a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLRenderer::GetTileProgramSwizzleOpaque(TexCoordPrecision precision,
2922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        SamplerType sampler) {
2923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TileProgramSwizzleOpaque* program =
2928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &tile_program_swizzle_opaque_[precision][sampler];
2929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleOpaque::initialize");
2931f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2932f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TileProgramSwizzleAA* GLRenderer::GetTileProgramSwizzleAA(
2938a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision,
2939a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SamplerType sampler) {
2940f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2941f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(sampler, 0);
2943f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(sampler, NumSamplerTypes);
2944a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TileProgramSwizzleAA* program = &tile_program_swizzle_aa_[precision][sampler];
2945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleAA::initialize");
2947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, sampler);
29492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram(
2954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TexCoordPrecision precision) {
2955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureProgram* program = &texture_program_[precision];
2958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
29592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
2960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
29622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst GLRenderer::NonPremultipliedTextureProgram*
2967a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLRenderer::GetNonPremultipliedTextureProgram(TexCoordPrecision precision) {
2968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NonPremultipliedTextureProgram* program =
2971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &nonpremultiplied_texture_program_[precision];
2972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
2973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT0("cc",
2974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
2975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
29772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst GLRenderer::TextureBackgroundProgram*
29827dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochGLRenderer::GetTextureBackgroundProgram(TexCoordPrecision precision) {
2983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureBackgroundProgram* program = &texture_background_program_[precision];
29867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!program->initialized()) {
29877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
2988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
2989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
29907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2991f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
29927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
29937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
29947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst GLRenderer::NonPremultipliedTextureBackgroundProgram*
29957dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochGLRenderer::GetNonPremultipliedTextureBackgroundProgram(
29967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TexCoordPrecision precision) {
2997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
2998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
2999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NonPremultipliedTextureBackgroundProgram* program =
3000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &nonpremultiplied_texture_background_program_[precision];
30017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!program->initialized()) {
30027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT0("cc",
30037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
3004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
30067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
30097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const GLRenderer::TextureProgram* GLRenderer::GetTextureIOSurfaceProgram(
3011a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TexCoordPrecision precision) {
3012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TextureProgram* program = &texture_io_surface_program_[precision];
3015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::textureIOSurfaceProgram::initialize");
3017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2DRect);
30192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram(
3024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TexCoordPrecision precision) {
3025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoYUVProgram* program = &video_yuv_program_[precision];
3028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize");
3030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
30322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const GLRenderer::VideoYUVAProgram* GLRenderer::GetVideoYUVAProgram(
3037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TexCoordPrecision precision) {
3038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3040f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoYUVAProgram* program = &video_yuva_program_[precision];
3041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!program->initialized()) {
3042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::videoYUVAProgram::initialize");
3043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        output_surface_->context_provider(), precision, SamplerType2D);
3045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
3046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
3047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GLRenderer::VideoStreamTextureProgram*
3050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLRenderer::GetVideoStreamTextureProgram(TexCoordPrecision precision) {
30512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Capabilities().using_egl_image)
30522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
3053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(precision, 0);
3054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_LT(precision, NumTexCoordPrecisions);
3055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoStreamTextureProgram* program =
3056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &video_stream_texture_program_[precision];
3057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!program->initialized()) {
30582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "GLRenderer::streamTextureProgram::initialize");
3059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    program->Initialize(
3060a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        output_surface_->context_provider(), precision, SamplerTypeExternalOES);
30612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return program;
30632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GLRenderer::CleanupSharedObjects() {
30662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shared_geometry_.reset();
30672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < NumTexCoordPrecisions; ++i) {
3069f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (int j = 0; j < NumSamplerTypes; ++j) {
3070a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_[i][j].Cleanup(gl_);
3071a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_opaque_[i][j].Cleanup(gl_);
3072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_[i][j].Cleanup(gl_);
3073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_opaque_[i][j].Cleanup(gl_);
3074a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_aa_[i][j].Cleanup(gl_);
3075a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tile_program_swizzle_aa_[i][j].Cleanup(gl_);
3076f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
3077f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3078a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_program_[i].Cleanup(gl_);
3079a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_program_[i].Cleanup(gl_);
3080a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_program_aa_[i].Cleanup(gl_);
3081a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_program_aa_[i].Cleanup(gl_);
3082a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_color_matrix_program_[i].Cleanup(gl_);
3083a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_color_matrix_program_aa_[i].Cleanup(gl_);
3084a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_color_matrix_program_aa_[i].Cleanup(gl_);
3085a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_pass_mask_color_matrix_program_[i].Cleanup(gl_);
3086f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3087a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_program_[i].Cleanup(gl_);
3088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    nonpremultiplied_texture_program_[i].Cleanup(gl_);
3089a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_background_program_[i].Cleanup(gl_);
3090a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    nonpremultiplied_texture_background_program_[i].Cleanup(gl_);
3091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    texture_io_surface_program_[i].Cleanup(gl_);
3092f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3093a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_yuv_program_[i].Cleanup(gl_);
3094a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_yuva_program_[i].Cleanup(gl_);
3095a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    video_stream_texture_program_[i].Cleanup(gl_);
3096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3098a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  tile_checkerboard_program_.Cleanup(gl_);
3099f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  debug_border_program_.Cleanup(gl_);
3101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  solid_color_program_.Cleanup(gl_);
3102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  solid_color_program_aa_.Cleanup(gl_);
31032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (offscreen_framebuffer_id_)
3105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl_, gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_));
31062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (on_demand_tile_raster_resource_id_)
3108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
3109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReleaseRenderPassTextures();
31112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
311390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GLRenderer::ReinitializeGLState() {
311490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Bind the common vertex attributes used for drawing all the layers.
311590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shared_geometry_->PrepareForDraw();
311690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_DEPTH_TEST));
3118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_CULL_FACE));
3119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->ColorMask(true, true, true, true));
3120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
3121fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  stencil_shadow_ = false;
3122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Enable(GL_BLEND));
312390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  blend_shadow_ = true;
3124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
3125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
312690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  program_shadow_ = 0;
312790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
312890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure scissoring starts as disabled.
312990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  is_scissor_enabled_ = false;
3130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
3131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scissor_rect_needs_reset_ = true;
313290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
313390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLRenderer::IsContextLost() {
3135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return output_surface_->context_provider()->IsContextLost();
31362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
3139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!frame->overlay_list.size())
3140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
3141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ResourceProvider::ResourceIdArray resources;
3143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OverlayCandidateList& overlays = frame->overlay_list;
3144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OverlayCandidateList::iterator it;
3145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  for (it = overlays.begin(); it != overlays.end(); ++it) {
3146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const OverlayCandidate& overlay = *it;
3147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Skip primary plane.
3148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (overlay.plane_z_order == 0)
3149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      continue;
3150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    pending_overlay_resources_.push_back(
3152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        make_scoped_ptr(new ResourceProvider::ScopedReadLockGL(
3153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            resource_provider(), overlay.resource_id)));
3154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_support_->ScheduleOverlayPlane(
3156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.plane_z_order,
3157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.transform,
3158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        pending_overlay_resources_.back()->texture_id(),
3159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.display_rect,
3160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        overlay.uv_rect);
3161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
3162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
3163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
31642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
3165