Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cc / layers / picture_layer.cc
index 6707307..d175a57 100644 (file)
@@ -4,9 +4,11 @@
 
 #include "cc/layers/picture_layer.h"
 
+#include "base/auto_reset.h"
 #include "cc/layers/content_layer_client.h"
 #include "cc/layers/picture_layer_impl.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "ui/gfx/rect_conversions.h"
 
 namespace cc {
@@ -16,20 +18,16 @@ scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) {
 }
 
 PictureLayer::PictureLayer(ContentLayerClient* client)
-  : client_(client),
-    pile_(make_scoped_refptr(new PicturePile())),
-    instrumentation_object_tracker_(id()),
-    is_mask_(false),
-    update_source_frame_number_(-1) {
+    : client_(client),
+      pile_(make_scoped_refptr(new PicturePile())),
+      instrumentation_object_tracker_(id()),
+      update_source_frame_number_(-1),
+      can_use_lcd_text_last_frame_(can_use_lcd_text()) {
 }
 
 PictureLayer::~PictureLayer() {
 }
 
-bool PictureLayer::DrawsContent() const {
-  return Layer::DrawsContent() && client_;
-}
-
 scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
   return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
 }
@@ -42,15 +40,15 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
     // Update may not get called for an empty layer, so resize here instead.
     // Using layer_impl because either bounds() or paint_properties().bounds
     // may disagree and either one could have been pushed to layer_impl.
-    pile_->Resize(gfx::Size());
-    pile_->UpdateRecordedRegion();
+    pile_->SetEmptyBounds();
   } else if (update_source_frame_number_ ==
              layer_tree_host()->source_frame_number()) {
+    // TODO(ernstm): This DCHECK is only valid as long as the pile's tiling_rect
+    // is identical to the layer_rect.
     // If update called, then pile size must match bounds pushed to impl layer.
-    DCHECK_EQ(layer_impl->bounds().ToString(), pile_->size().ToString());
+    DCHECK_EQ(layer_impl->bounds().ToString(), pile_->tiling_size().ToString());
   }
 
-  layer_impl->SetIsMask(is_mask_);
   // Unlike other properties, invalidation must always be set on layer_impl.
   // See PictureLayerImpl::PushPropertiesTo for more details.
   layer_impl->invalidation_.Clear();
@@ -81,13 +79,22 @@ void PictureLayer::SetNeedsDisplayRect(const gfx::RectF& layer_rect) {
 }
 
 bool PictureLayer::Update(ResourceUpdateQueue* queue,
-                          const OcclusionTracker* occlusion) {
+                          const OcclusionTracker<Layer>* occlusion) {
   update_source_frame_number_ = layer_tree_host()->source_frame_number();
   bool updated = Layer::Update(queue, occlusion);
 
+  {
+    base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
+                                                  true);
+    UpdateCanUseLCDText();
+  }
+
+  gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
+      visible_content_rect(), 1.f / contents_scale_x());
+  gfx::Size layer_size = paint_properties().bounds;
+
   if (last_updated_visible_content_rect_ == visible_content_rect() &&
-      pile_->size() == paint_properties().bounds &&
-      pending_invalidation_.IsEmpty()) {
+      pile_->tiling_size() == layer_size && pending_invalidation_.IsEmpty()) {
     // Only early out if the visible content rect of this layer hasn't changed.
     return updated;
   }
@@ -95,28 +102,36 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue,
   TRACE_EVENT1("cc", "PictureLayer::Update",
                "source_frame_number",
                layer_tree_host()->source_frame_number());
-
-  pile_->Resize(paint_properties().bounds);
+  devtools_instrumentation::ScopedLayerTreeTask update_layer(
+      devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id());
 
   // Calling paint in WebKit can sometimes cause invalidations, so save
   // off the invalidation prior to calling update.
   pending_invalidation_.Swap(&pile_invalidation_);
   pending_invalidation_.Clear();
 
-  gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
-      visible_content_rect(), 1.f / contents_scale_x());
-  if (layer_tree_host()->settings().using_synchronous_renderer_compositor) {
+  if (layer_tree_host()->settings().record_full_layer) {
     // Workaround for http://crbug.com/235910 - to retain backwards compat
     // the full page content must always be provided in the picture layer.
-    visible_layer_rect = gfx::Rect(bounds());
+    visible_layer_rect = gfx::Rect(layer_size);
   }
-  updated |= pile_->Update(client_,
-                           SafeOpaqueBackgroundColor(),
-                           contents_opaque(),
-                           pile_invalidation_,
-                           visible_layer_rect,
-                           update_source_frame_number_,
-                           rendering_stats_instrumentation());
+
+  // UpdateAndExpandInvalidation will give us an invalidation that covers
+  // anything not explicitly recorded in this frame. We give this region
+  // to the impl side so that it drops tiles that may not have a recording
+  // for them.
+  DCHECK(client_);
+  updated |=
+      pile_->UpdateAndExpandInvalidation(client_,
+                                         &pile_invalidation_,
+                                         SafeOpaqueBackgroundColor(),
+                                         contents_opaque(),
+                                         client_->FillsBoundsCompletely(),
+                                         layer_size,
+                                         visible_layer_rect,
+                                         update_source_frame_number_,
+                                         RecordingMode(),
+                                         rendering_stats_instrumentation());
   last_updated_visible_content_rect_ = visible_content_rect();
 
   if (updated) {
@@ -131,13 +146,33 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue,
 }
 
 void PictureLayer::SetIsMask(bool is_mask) {
-  is_mask_ = is_mask;
+  pile_->set_is_mask(is_mask);
+}
+
+Picture::RecordingMode PictureLayer::RecordingMode() const {
+  switch (layer_tree_host()->settings().recording_mode) {
+    case LayerTreeSettings::RecordNormally:
+      return Picture::RECORD_NORMALLY;
+    case LayerTreeSettings::RecordWithSkRecord:
+      return Picture::RECORD_WITH_SKRECORD;
+  }
+  NOTREACHED();
+  return Picture::RECORD_NORMALLY;
 }
 
 bool PictureLayer::SupportsLCDText() const {
   return true;
 }
 
+void PictureLayer::UpdateCanUseLCDText() {
+  if (can_use_lcd_text_last_frame_ == can_use_lcd_text())
+    return;
+
+  can_use_lcd_text_last_frame_ = can_use_lcd_text();
+  if (client_)
+    client_->DidChangeLayerCanUseLCDText();
+}
+
 skia::RefPtr<SkPicture> PictureLayer::GetPicture() const {
   // We could either flatten the PicturePile into a single SkPicture,
   // or paint a fresh one depending on what we intend to do with the
@@ -147,15 +182,29 @@ skia::RefPtr<SkPicture> PictureLayer::GetPicture() const {
 
   int width = bounds().width();
   int height = bounds().height();
-  gfx::RectF opaque;
 
-  skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
-  SkCanvas* canvas = picture->beginRecording(width, height);
-  client_->PaintContents(canvas, gfx::Rect(width, height), &opaque);
-  picture->endRecording();
+  SkPictureRecorder recorder;
+  SkCanvas* canvas = recorder.beginRecording(width, height, NULL, 0);
+  client_->PaintContents(canvas,
+                         gfx::Rect(width, height),
+                         ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
+  skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
   return picture;
 }
 
+bool PictureLayer::IsSuitableForGpuRasterization() const {
+  return pile_->is_suitable_for_gpu_rasterization();
+}
+
+void PictureLayer::ClearClient() {
+  client_ = NULL;
+  UpdateDrawsContent(HasDrawableContent());
+}
+
+bool PictureLayer::HasDrawableContent() const {
+  return client_ && Layer::HasDrawableContent();
+}
+
 void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
   benchmark->RunOnLayer(this);
 }