blob: 437f6884172edf295489b86cf95a06f6a10965df [file] [log] [blame]
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_
#include <memory>
#include "base/dcheck_is_on.h"
#include "cc/input/scroll_snap_data.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h"
#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkFilterQuality.h"
#include "third_party/skia/include/core/SkRefCnt.h"
namespace cc {
class DisplayItemList;
class PictureLayer;
} // namespace cc
namespace blink {
class PaintController;
class RasterInvalidationTracking;
class RasterInvalidator;
struct PreCompositedLayerInfo;
typedef Vector<GraphicsLayer*, 64> GraphicsLayerVector;
// GraphicsLayer is an abstraction for a rendering surface with backing store,
// which may have associated transformation and animations.
class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
public LayerAsJSONClient,
private cc::ContentLayerClient {
USING_FAST_MALLOC(GraphicsLayer);
public:
explicit GraphicsLayer(GraphicsLayerClient&);
GraphicsLayer(const GraphicsLayer&) = delete;
GraphicsLayer& operator=(const GraphicsLayer&) = delete;
~GraphicsLayer() override;
GraphicsLayerClient& Client() const { return client_; }
void SetCompositingReasons(CompositingReasons reasons) {
compositing_reasons_ = reasons;
}
CompositingReasons GetCompositingReasons() const {
return compositing_reasons_;
}
SquashingDisallowedReasons GetSquashingDisallowedReasons() const {
return squashing_disallowed_reasons_;
}
void SetSquashingDisallowedReasons(SquashingDisallowedReasons reasons) {
squashing_disallowed_reasons_ = reasons;
}
void SetOwnerNodeId(DOMNodeId id) { owner_node_id_ = id; }
GraphicsLayer* Parent() const { return parent_; }
void SetParent(GraphicsLayer*); // Internal use only.
const Vector<GraphicsLayer*>& Children() const { return children_; }
// Returns true if the child list changed.
bool SetChildren(const GraphicsLayerVector&);
// Add child layers. If the child is already parented, it will be removed from
// its old parent.
void AddChild(GraphicsLayer*);
void RemoveAllChildren();
void RemoveFromParent();
// The offset is the origin of the layoutObject minus the origin of the
// graphics layer (so either zero or negative).
IntSize OffsetFromLayoutObject() const { return offset_from_layout_object_; }
void SetOffsetFromLayoutObject(const IntSize&);
// The size of the layer.
const gfx::Size& Size() const;
void SetSize(const gfx::Size&);
bool DrawsContent() const { return draws_content_; }
void SetDrawsContent(bool);
// False if no hit test data will be recorded onto this GraphicsLayer.
// This is different from |DrawsContent| because hit test data are internal
// to blink and are not copied to the cc::Layer's display list.
bool PaintsHitTest() const { return paints_hit_test_; }
void SetPaintsHitTest(bool);
bool PaintsContentOrHitTest() const {
return draws_content_ || paints_hit_test_;
}
bool ContentsAreVisible() const { return contents_visible_; }
void SetContentsVisible(bool);
void SetHitTestable(bool);
bool IsHitTestable() const { return hit_testable_; }
// Some GraphicsLayers paint only the foreground or the background content
GraphicsLayerPaintingPhase PaintingPhase() const { return painting_phase_; }
void SetPaintingPhase(GraphicsLayerPaintingPhase);
void InvalidateContents();
// Set that the position/size of the contents (image or video).
void SetContentsRect(const IntRect&);
void SetContentsToCcLayer(scoped_refptr<cc::Layer> contents_layer);
bool HasContentsLayer() const { return ContentsLayer(); }
cc::Layer* ContentsLayer() const { return contents_layer_.get(); }
const IntRect& ContentsRect() const { return contents_rect_; }
// For hosting this GraphicsLayer in a native layer hierarchy.
cc::PictureLayer& CcLayer() const { return *layer_; }
bool IsTrackingRasterInvalidations() const;
void UpdateTrackingRasterInvalidations();
void ResetTrackedRasterInvalidations();
bool HasTrackedRasterInvalidations() const;
RasterInvalidationTracking* GetRasterInvalidationTracking() const;
void TrackRasterInvalidation(const DisplayItemClient&,
const IntRect&,
PaintInvalidationReason);
// Returns true if any layer is repainted.
bool PaintRecursively(GraphicsContext&,
Vector<PreCompositedLayerInfo>&,
PaintBenchmarkMode = PaintBenchmarkMode::kNormal);
PaintController& GetPaintController() const;
void SetElementId(const CompositorElementId&);
// DisplayItemClient methods
String DebugName() const final { return client_.DebugName(this); }
DOMNodeId OwnerNodeId() const final { return owner_node_id_; }
// LayerAsJSONClient implementation.
void AppendAdditionalInfoAsJSON(LayerTreeFlags,
const cc::Layer&,
JSONObject&) const override;
bool HasLayerState() const { return layer_state_.get(); }
void SetLayerState(const PropertyTreeStateOrAlias&,
const IntPoint& layer_offset);
PropertyTreeStateOrAlias GetPropertyTreeState() const {
return layer_state_->state.GetPropertyTreeState();
}
IntPoint GetOffsetFromTransformNode() const { return layer_state_->offset; }
void SetContentsLayerState(const PropertyTreeStateOrAlias&,
const IntPoint& layer_offset);
PropertyTreeStateOrAlias GetContentsPropertyTreeState() const {
return contents_layer_state_
? contents_layer_state_->state.GetPropertyTreeState()
: GetPropertyTreeState();
}
IntPoint GetContentsOffsetFromTransformNode() const {
return contents_layer_state_ ? contents_layer_state_->offset
: GetOffsetFromTransformNode();
}
void SetNeedsCheckRasterInvalidation() {
needs_check_raster_invalidation_ = true;
}
void PaintForTesting(const IntRect& interest_rect);
void SetShouldCreateLayersAfterPaint(bool);
bool ShouldCreateLayersAfterPaint() const {
return should_create_layers_after_paint_;
}
// Whether this GraphicsLayer is repainted in the last Paint().
bool Repainted() const { return repainted_; }
size_t ApproximateUnsharedMemoryUsageRecursive() const;
protected:
String DebugName(const cc::Layer*) const;
private:
friend class CompositedLayerMappingTest;
friend class GraphicsLayerTest;
// cc::ContentLayerClient implementation.
gfx::Rect PaintableRegion() const final;
scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList() final;
bool FillsBoundsCompletely() const final { return false; }
void ClearPaintStateRecursively();
void Paint(Vector<PreCompositedLayerInfo>&,
PaintBenchmarkMode,
const IntRect* interest_rect = nullptr);
// Adds a child without calling NotifyChildListChange(), so that adding
// children can be batched before updating.
void AddChildInternal(GraphicsLayer*);
#if DCHECK_IS_ON()
bool HasAncestor(GraphicsLayer*) const;
#endif
// Helper functions used by settors to keep layer's the state consistent.
void NotifyChildListChange();
void UpdateLayerIsDrawable();
void UpdateContentsLayerBounds();
void SetContentsTo(scoped_refptr<cc::Layer>);
RasterInvalidator& EnsureRasterInvalidator();
void InvalidateRaster(const IntRect&);
GraphicsLayerClient& client_;
// Offset from the owning layoutObject
IntSize offset_from_layout_object_;
TransformationMatrix transform_;
bool draws_content_ : 1;
bool paints_hit_test_ : 1;
bool contents_visible_ : 1;
bool hit_testable_ : 1;
bool needs_check_raster_invalidation_ : 1;
bool raster_invalidated_ : 1;
// True if the cc::Layers for this GraphicsLayer should be created after
// paint (in PaintArtifactCompositor). This depends on the display item list
// and is updated after CommitNewDisplayItems.
bool should_create_layers_after_paint_ : 1;
bool repainted_ : 1;
GraphicsLayerPaintingPhase painting_phase_;
Vector<GraphicsLayer*> children_;
GraphicsLayer* parent_;
IntRect contents_rect_;
scoped_refptr<cc::PictureLayer> layer_;
scoped_refptr<cc::Layer> contents_layer_;
scoped_refptr<cc::DisplayItemList> cc_display_item_list_;
SquashingDisallowedReasons squashing_disallowed_reasons_ =
SquashingDisallowedReason::kNone;
mutable std::unique_ptr<PaintController> paint_controller_;
// Used only when CullRectUpdate is not enabled.
IntRect previous_interest_rect_;
struct LayerState {
// In theory, it's unnecessary to use RefCountedPropertyTreeState because
// when it's used, the state should always reference current paint property
// nodes in ObjectPaintProperties. This is to workaround under-invalidation
// of layer state.
RefCountedPropertyTreeState state;
IntPoint offset;
};
std::unique_ptr<LayerState> layer_state_;
std::unique_ptr<LayerState> contents_layer_state_;
std::unique_ptr<RasterInvalidator> raster_invalidator_;
RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_;
DOMNodeId owner_node_id_ = kInvalidDOMNodeId;
CompositingReasons compositing_reasons_ = CompositingReason::kNone;
};
// Iterates all graphics layers that should be seen by the compositor in
// pre-order. |GraphicsLayerType&| matches |GraphicsLayer&| or
// |const GraphicsLayer&|. |GraphicsLayerFunction| accepts a GraphicsLayerType
// parameter, and returns a bool to indicate if the recursion should continue.
template <typename GraphicsLayerType,
typename GraphicsLayerFunction,
typename ContentsLayerFunction>
void ForAllGraphicsLayers(
GraphicsLayerType& layer,
const GraphicsLayerFunction& graphics_layer_function,
const ContentsLayerFunction& contents_layer_function) {
if (!graphics_layer_function(layer))
return;
if (auto* contents_layer = layer.ContentsLayer())
contents_layer_function(layer, *contents_layer);
for (auto* child : layer.Children()) {
ForAllGraphicsLayers(*child, graphics_layer_function,
contents_layer_function);
}
}
// Unlike ForAllGraphicsLayers, here |GraphicsLayerFunction| should return void.
template <typename GraphicsLayerType,
typename GraphicsLayerFunction,
typename ContentsLayerFunction>
void ForAllActiveGraphicsLayers(
GraphicsLayerType& layer,
const GraphicsLayerFunction& graphics_layer_function,
const ContentsLayerFunction& contents_layer_function) {
ForAllGraphicsLayers(
layer,
[&graphics_layer_function](GraphicsLayerType& layer) -> bool {
if (layer.Client().ShouldSkipPaintingSubtree())
return false;
if (layer.PaintsContentOrHitTest() || layer.IsHitTestable())
graphics_layer_function(layer);
return true;
},
contents_layer_function);
}
template <typename GraphicsLayerType, typename Function>
void ForAllActiveGraphicsLayers(GraphicsLayerType& layer,
const Function& function) {
ForAllActiveGraphicsLayers(layer, function,
[](GraphicsLayerType&, const cc::Layer&) {});
}
template <typename GraphicsLayerType, typename Function>
void ForAllPaintingGraphicsLayers(GraphicsLayerType& layer,
const Function& function) {
ForAllActiveGraphicsLayers(layer, [&function](GraphicsLayerType& layer) {
if (layer.PaintsContentOrHitTest())
function(layer);
});
}
} // namespace blink
#if DCHECK_IS_ON()
// Outside the blink namespace for ease of invocation from gdb.
PLATFORM_EXPORT void showGraphicsLayerTree(const blink::GraphicsLayer*);
#endif
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_