12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 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)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/layers/nine_patch_layer_impl.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "cc/base/math_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/texture_draw_quad.h"
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "cc/trees/occlusion_tracker.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_f.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NinePatchLayerImpl::NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id)
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : UIResourceLayerImpl(tree_impl, id),
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      fill_center_(false) {}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NinePatchLayerImpl::~NinePatchLayerImpl() {}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> NinePatchLayerImpl::CreateLayerImpl(
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NinePatchLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NinePatchLayerImpl::PushPropertiesTo(LayerImpl* layer) {
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UIResourceLayerImpl::PushPropertiesTo(layer);
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layer_impl->SetLayout(image_aperture_, border_, fill_center_);
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static gfx::RectF NormalizedRect(float x,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 float y,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 float width,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 float height,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 float total_width,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 float total_height) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::RectF(x / total_width,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    y / total_height,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    width / total_width,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    height / total_height);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NinePatchLayerImpl::SetLayout(const gfx::Rect& aperture,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   const gfx::Rect& border,
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   bool fill_center) {
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // This check imposes an ordering on the call sequence.  An UIResource must
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // exist before SetLayout can be called.
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(ui_resource_id_);
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (image_aperture_ == aperture &&
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      border_ == border && fill_center_ == fill_center)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  image_aperture_ = aperture;
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  border_ = border;
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fill_center_ = fill_center;
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NoteLayerPropertyChanged();
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NinePatchLayerImpl::CheckGeometryLimitations() {
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // |border| is in layer space.  It cannot exceed the bounds of the layer.
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_GE(bounds().width(), border_.width());
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_GE(bounds().height(), border_.height());
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Sanity Check on |border|
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_LE(border_.x(), border_.width());
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_LE(border_.y(), border_.height());
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_GE(border_.x(), 0);
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_GE(border_.y(), 0);
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // |aperture| is in image space.  It cannot exceed the bounds of the bitmap.
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!image_aperture_.size().IsEmpty());
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(gfx::Rect(image_bounds_).Contains(image_aperture_))
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      << "image_bounds_ " << gfx::Rect(image_bounds_).ToString()
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      << " image_aperture_ " << image_aperture_.ToString();
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NinePatchLayerImpl::AppendQuads(
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderPass* render_pass,
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const OcclusionTracker<LayerImpl>& occlusion_tracker,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppendQuadsData* append_quads_data) {
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CheckGeometryLimitations();
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SharedQuadState* shared_quad_state =
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_pass->CreateAndAppendSharedQuadState();
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  PopulateSharedQuadState(shared_quad_state);
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendDebugBorderQuad(
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_pass, content_bounds(), shared_quad_state, append_quads_data);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!ui_resource_id_)
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId resource =
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!resource)
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const bool flipped = false;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const bool premultiplied_alpha = true;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!bounds().IsEmpty());
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // NinePatch border widths in layer space.
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_left_width = border_.x();
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_top_height = border_.y();
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_right_width = border_.width() - layer_left_width;
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_bottom_height = border_.height() - layer_top_height;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_middle_width = bounds().width() - border_.width();
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int layer_middle_height = bounds().height() - border_.height();
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Patch positions in layer space
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_top_left(0, 0, layer_left_width, layer_top_height);
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_top_right(bounds().width() - layer_right_width,
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            0,
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            layer_right_width,
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            layer_top_height);
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_bottom_left(0,
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                              bounds().height() - layer_bottom_height,
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                              layer_left_width,
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                              layer_bottom_height);
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_bottom_right(layer_top_right.x(),
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               layer_bottom_left.y(),
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               layer_right_width,
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               layer_bottom_height);
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_top(
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_top_left.right(), 0, layer_middle_width, layer_top_height);
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_left(
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      0, layer_top_left.bottom(), layer_left_width, layer_middle_height);
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_right(layer_top_right.x(),
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        layer_top_right.bottom(),
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        layer_right_width,
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        layer_left.height());
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_bottom(layer_top.x(),
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_bottom_left.y(),
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_top.width(),
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_bottom_height);
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect layer_center(layer_left_width,
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_top_height,
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_middle_width,
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         layer_middle_height);
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Note the following values are in image (bitmap) space.
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  float image_width = image_bounds_.width();
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  float image_height = image_bounds_.height();
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int image_aperture_left_width = image_aperture_.x();
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int image_aperture_top_height = image_aperture_.y();
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int image_aperture_right_width = image_width - image_aperture_.right();
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int image_aperture_bottom_height = image_height - image_aperture_.bottom();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Patch positions in bitmap UV space (from zero to one)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_top_left = NormalizedRect(0,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          0,
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                          image_aperture_left_width,
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                          image_aperture_top_height,
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                          image_width,
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                          image_height);
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::RectF uv_top_right =
16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      NormalizedRect(image_width - image_aperture_right_width,
16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     0,
16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_right_width,
16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_top_height,
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_width,
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_height);
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::RectF uv_bottom_left =
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      NormalizedRect(0,
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_height - image_aperture_bottom_height,
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_left_width,
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_bottom_height,
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_width,
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_height);
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::RectF uv_bottom_right =
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      NormalizedRect(image_width - image_aperture_right_width,
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_height - image_aperture_bottom_height,
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_right_width,
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_bottom_height,
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_width,
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_height);
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::RectF uv_top(
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      uv_top_left.right(),
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      0,
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      (image_width - image_aperture_left_width - image_aperture_right_width) /
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          image_width,
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      (image_aperture_top_height) / image_height);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_left(0,
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     uv_top_left.bottom(),
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     image_aperture_left_width / image_width,
19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     (image_height - image_aperture_top_height -
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                      image_aperture_bottom_height) /
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         image_height);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_right(uv_top_right.x(),
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                      uv_top_right.bottom(),
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                      image_aperture_right_width / image_width,
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                      uv_left.height());
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_bottom(uv_top.x(),
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       uv_bottom_left.y(),
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       uv_top.width(),
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       image_aperture_bottom_height / image_height);
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::RectF uv_center(uv_top_left.right(),
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       uv_top_left.bottom(),
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       uv_top.width(),
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       uv_left.height());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Nothing is opaque here.
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(danakj): Should we look at the SkBitmaps to determine opaqueness?
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_rect;
2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gfx::Rect visible_rect;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Occlusion occlusion =
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      occlusion_tracker.GetCurrentOcclusionForLayer(draw_transform());
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_top_left);
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_top_left,
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top_left.origin(),
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top_left.bottom_right(),
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_top_right);
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    quad->SetNew(shared_quad_state,
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_top_right,
24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 opaque_rect,
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 resource,
24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 premultiplied_alpha,
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top_right.origin(),
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top_right.bottom_right(),
24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 SK_ColorTRANSPARENT,
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 vertex_opacity,
25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 flipped);
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_bottom_left);
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_bottom_left,
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom_left.origin(),
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom_left.bottom_right(),
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_bottom_right);
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_bottom_right,
2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom_right.origin(),
2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom_right.bottom_right(),
2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
2840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_top);
2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_top,
2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top.origin(),
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_top.bottom_right(),
2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_left);
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_left,
3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_left.origin(),
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_left.bottom_right(),
3160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
3170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
3180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_right);
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
3260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_right,
3270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_right,
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
3300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
3310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_right.origin(),
3320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_right.bottom_right(),
3330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
3340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
3350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
3360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  visible_rect = occlusion.GetUnoccludedContentRect(layer_bottom);
3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!visible_rect.IsEmpty()) {
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TextureDrawQuad* quad =
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
3420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    quad->SetNew(shared_quad_state,
3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 layer_bottom,
3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 opaque_rect,
3450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 visible_rect,
3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 resource,
3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 premultiplied_alpha,
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom.origin(),
3490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 uv_bottom.bottom_right(),
3500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 SK_ColorTRANSPARENT,
3510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 vertex_opacity,
3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 flipped);
3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (fill_center_) {
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    visible_rect = occlusion.GetUnoccludedContentRect(layer_center);
3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!visible_rect.IsEmpty()) {
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      TextureDrawQuad* quad =
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
3600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      quad->SetNew(shared_quad_state,
3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   layer_center,
3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   opaque_rect,
3630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   visible_rect,
3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   resource,
3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   premultiplied_alpha,
3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   uv_center.origin(),
3670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   uv_center.bottom_right(),
3680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   SK_ColorTRANSPARENT,
3690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   vertex_opacity,
3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   flipped);
3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* NinePatchLayerImpl::LayerTypeAsString() const {
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return "cc::NinePatchLayerImpl";
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* NinePatchLayerImpl::LayerTreeAsJson() const {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* result = LayerImpl::LayerTreeAsJson();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* list = new base::ListValue;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list->AppendInteger(image_aperture_.origin().x());
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list->AppendInteger(image_aperture_.origin().y());
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list->AppendInteger(image_aperture_.size().width());
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list->AppendInteger(image_aperture_.size().height());
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result->Set("ImageAperture", list);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  list = new base::ListValue;
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  list->AppendInteger(image_bounds_.width());
391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  list->AppendInteger(image_bounds_.height());
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  result->Set("ImageBounds", list);
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  result->Set("Border", MathUtil::AsValue(border_).release());
39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  result->SetBoolean("FillCenter", fill_center_);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
402