Wire up OpacityLayer to Scenic

This commit is contained in:
David Worsham
2019-11-26 15:49:59 -08:00
parent c4df6dfeed
commit ea67e5b0b9
11 changed files with 200 additions and 175 deletions
+16 -1
View File
@@ -20,10 +20,25 @@ ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id,
void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "ChildSceneLayer::Preroll");
set_needs_system_composite(true);
// An alpha "hole punch" is required if the frame behind us is not opaque.
if (!context->is_opaque) {
set_paint_bounds(
SkRect::MakeXYWH(offset_.fX, offset_.fY, size_.fWidth, size_.fHeight));
}
}
void ChildSceneLayer::Paint(PaintContext& context) const {
FML_NOTREACHED() << "This layer never needs painting.";
TRACE_EVENT0("flutter", "ChildSceneLayer::Paint");
FML_DCHECK(needs_painting());
// If we are being rendered into our own frame using the system compositor,
// then it is neccesary to "punch a hole" in the canvas/frame behind us so
// that group opacity looks correct.
SkPaint paint;
paint.setColor(SK_ColorTRANSPARENT);
paint.setBlendMode(SkBlendMode::kSrc);
context.leaf_nodes_canvas->drawRect(paint_bounds(), paint);
}
void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) {
+17 -3
View File
@@ -7,8 +7,21 @@
namespace flutter {
FuchsiaSystemCompositedLayer::FuchsiaSystemCompositedLayer(SkColor color,
SkAlpha opacity,
float elevation)
: ElevatedContainerLayer(elevation), color_(color) {}
: ElevatedContainerLayer(elevation), color_(color), opacity_(opacity) {}
void FuchsiaSystemCompositedLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "FuchsiaSystemCompositedLayer::Preroll");
const float parent_is_opaque = context->is_opaque;
context->mutators_stack.PushOpacity(opacity_);
context->is_opaque = parent_is_opaque && (opacity_ == SK_AlphaOPAQUE);
ElevatedContainerLayer::Preroll(context, matrix);
context->is_opaque = parent_is_opaque;
context->mutators_stack.Pop();
}
void FuchsiaSystemCompositedLayer::UpdateScene(SceneUpdateContext& context) {
FML_DCHECK(needs_system_composite());
@@ -28,14 +41,15 @@ void FuchsiaSystemCompositedLayer::UpdateScene(SceneUpdateContext& context) {
TRACE_EVENT_INSTANT0("flutter", "retained cache miss, creating");
// If we can't find an existing retained surface, create one.
SceneUpdateContext::Frame frame(context, rrect_, color_, elevation(), this);
SceneUpdateContext::Frame frame(context, rrect_, color_, opacity_ / 255.0f,
elevation(), this);
for (auto& layer : layers()) {
if (layer->needs_painting()) {
frame.AddPaintLayer(layer.get());
}
}
ContainerLayer::UpdateScene(context);
ElevatedContainerLayer::UpdateScene(context);
}
} // namespace flutter
@@ -14,17 +14,20 @@ class FuchsiaSystemCompositedLayer : public ElevatedContainerLayer {
public:
static bool can_system_composite() { return true; }
FuchsiaSystemCompositedLayer(SkColor color, float elevation);
FuchsiaSystemCompositedLayer(SkColor color, SkAlpha opacity, float elevation);
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void UpdateScene(SceneUpdateContext& context) override;
void set_dimensions(SkRRect rrect) { rrect_ = rrect; }
SkColor color() const { return color_; }
SkAlpha opacity() const { return opacity_; }
private:
SkRRect rrect_ = SkRRect::MakeEmpty();
SkColor color_ = SK_ColorTRANSPARENT;
SkAlpha opacity_ = SK_AlphaOPAQUE;
FML_DISALLOW_COPY_AND_ASSIGN(FuchsiaSystemCompositedLayer);
};
+3 -2
View File
@@ -60,10 +60,11 @@ struct PrerollContext {
float frame_physical_depth;
float frame_device_pixel_ratio;
// These allow us to track properties like elevation and opacity which stack
// with each other during Preroll.
// These allow us to track properties like elevation, opacity, and the
// prescence of a platform view during Preroll.
float total_elevation = 0.0f;
bool has_platform_view = false;
bool is_opaque = true;
};
// Represents a single composited layer. Created on the UI thread but then
+56 -15
View File
@@ -9,8 +9,29 @@
namespace flutter {
OpacityLayer::OpacityLayer(int alpha, const SkPoint& offset)
: alpha_(alpha), offset_(offset) {
// The OpacityLayer has no real "elevation", but we want to avoid Z-fighting
// when using the system compositor. Choose a small but non-zero value for
// this.
constexpr float kOpacityElevationWhenUsingSystemCompositor = 0.01f;
#if !defined(OS_FUCHSIA)
void OpacityLayerBase::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
const float parent_is_opaque = context->is_opaque;
context->mutators_stack.PushOpacity(opacity_);
context->is_opaque = parent_is_opaque && (opacity_ == SK_AlphaOPAQUE);
ContainerLayer::Preroll(context, matrix);
context->is_opaque = parent_is_opaque;
context->mutators_stack.Pop();
}
#endif
OpacityLayer::OpacityLayer(SkAlpha opacity, const SkPoint& offset)
: OpacityLayerBase(SK_ColorTRANSPARENT,
opacity,
kOpacityElevationWhenUsingSystemCompositor),
offset_(offset) {
// Ensure OpacityLayer has only one direct child.
//
// This is needed to ensure that retained rendering can always be applied to
@@ -31,32 +52,53 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
ContainerLayer* container = GetChildContainer();
FML_DCHECK(!container->layers().empty()); // OpacityLayer can't be a leaf.
// Factor in the offset during Preroll. |OpacityLayerBase| will handle the
// opacity.
SkMatrix child_matrix = matrix;
child_matrix.postTranslate(offset_.fX, offset_.fY);
context->mutators_stack.PushTransform(
SkMatrix::MakeTrans(offset_.fX, offset_.fY));
context->mutators_stack.PushOpacity(alpha_);
ContainerLayer::Preroll(context, child_matrix);
OpacityLayerBase::Preroll(context, child_matrix);
context->mutators_stack.Pop();
context->mutators_stack.Pop();
set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY));
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, paint_bounds())) {
SkMatrix ctm = child_matrix;
// When using the system compositor, do not include the offset since we are
// rendering as a separate piece of geometry and the offset will be baked into
// that geometry's transform.
if (OpacityLayerBase::can_system_composite()) {
set_dimensions(SkRRect::MakeRect(paint_bounds()));
set_needs_system_composite(true);
} else {
set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY));
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, paint_bounds())) {
SkMatrix ctm = child_matrix;
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
ctm = RasterCache::GetIntegralTransCTM(ctm);
ctm = RasterCache::GetIntegralTransCTM(ctm);
#endif
context->raster_cache->Prepare(context, container, ctm);
context->raster_cache->Prepare(context, container, ctm);
}
}
}
#if defined(OS_FUCHSIA)
void OpacityLayer::UpdateScene(SceneUpdateContext& context) {
SceneUpdateContext::Transform transform(
context, SkMatrix::MakeTrans(offset_.fX, offset_.fY));
// OpacityLayerBase will handle applying the opacity itself.
OpacityLayerBase::UpdateScene(context);
}
#endif
void OpacityLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "OpacityLayer::Paint");
FML_DCHECK(needs_painting());
SkPaint paint;
paint.setAlpha(alpha_);
paint.setAlpha(opacity());
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->translate(offset_.fX, offset_.fY);
@@ -83,8 +125,7 @@ void OpacityLayer::Paint(PaintContext& context) const {
// RasterCache::GetIntegralTransCTM optimization.
//
// Note that the following lines are only accessible when the raster cache is
// not available (e.g., when we're using the software backend in golden
// tests).
// not available, or when a cache miss occurs.
SkRect saveLayerBounds;
paint_bounds()
.makeOffset(-offset_.fX, -offset_.fY)
@@ -92,7 +133,7 @@ void OpacityLayer::Paint(PaintContext& context) const {
Layer::AutoSaveLayer save_layer =
Layer::AutoSaveLayer::Create(context, saveLayerBounds, &paint);
PaintChildren(context);
OpacityLayerBase::Paint(context);
}
ContainerLayer* OpacityLayer::GetChildContainer() const {
+33 -8
View File
@@ -5,15 +5,42 @@
#ifndef FLUTTER_FLOW_LAYERS_OPACITY_LAYER_H_
#define FLUTTER_FLOW_LAYERS_OPACITY_LAYER_H_
#include "flutter/flow/layers/container_layer.h"
#include "flutter/flow/layers/elevated_container_layer.h"
#if defined(OS_FUCHSIA)
#include "flutter/flow/layers/fuchsia_system_composited_layer.h"
#endif
namespace flutter {
#if !defined(OS_FUCHSIA)
class OpacityLayerBase : public ContainerLayer {
public:
static bool can_system_composite() { return false; }
OpacityLayerBase(SkColor color, SkAlpha opacity, float elevation)
: color_(color), opacity_(opacity) {}
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void set_dimensions(SkRRect rrect) {}
SkColor color() const { return color_; }
SkAlpha opacity() const { return opacity_; }
float elevation() const { return 0; }
private:
SkColor color_;
SkAlpha opacity_;
};
#else
using OpacityLayerBase = FuchsiaSystemCompositedLayer;
#endif
// Don't add an OpacityLayer with no children to the layer tree. Painting an
// OpacityLayer is very costly due to the saveLayer call. If there's no child,
// having the OpacityLayer or not has the same effect. In debug_unopt build,
// |Preroll| will assert if there are no children.
class OpacityLayer : public ContainerLayer {
class OpacityLayer : public OpacityLayerBase {
public:
// An offset is provided here because OpacityLayer.addToScene method in the
// Flutter framework can take an optional offset argument.
@@ -25,21 +52,19 @@ class OpacityLayer : public ContainerLayer {
// the retained rendering inefficient as a small offset change could propagate
// to many leaf layers. Therefore we try to capture that offset here to stop
// the propagation as repainting the OpacityLayer is expensive.
OpacityLayer(int alpha, const SkPoint& offset);
OpacityLayer(SkAlpha alpha, const SkPoint& offset);
void Add(std::shared_ptr<Layer> layer) override;
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
#if defined(OS_FUCHSIA)
void UpdateScene(SceneUpdateContext& context) override;
#endif
void Paint(PaintContext& context) const override;
// TODO(chinmaygarde): Once SCN-139 is addressed, introduce a new node in the
// session scene hierarchy.
private:
ContainerLayer* GetChildContainer() const;
int alpha_;
SkPoint offset_;
FML_DISALLOW_COPY_AND_ASSIGN(OpacityLayer);
+2 -40
View File
@@ -17,7 +17,7 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color,
float elevation,
const SkPath& path,
Clip clip_behavior)
: PhysicalShapeLayerBase(color, elevation),
: PhysicalShapeLayerBase(color, SK_AlphaOPAQUE, elevation),
shadow_color_(shadow_color),
path_(path),
isRect_(false),
@@ -58,53 +58,15 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context,
set_needs_system_composite(true);
return;
}
//#if defined(OS_FUCHSIA)
// // Let the system compositor draw all shadows for us.
// set_needs_system_composite(true);
//#else
// We will draw the shadow in Paint(), so add some margin to the paint
// bounds to leave space for the shadow. We fill this whole region and clip
// children to it so we don't need to join the child paint bounds.
set_paint_bounds(ComputeShadowBounds(path_.getBounds(), elevation(),
context->frame_device_pixel_ratio));
//#endif // defined(OS_FUCHSIA)
}
}
#if defined(OS_FUCHSIA)
void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) {
FML_DCHECK(needs_system_composite());
TRACE_EVENT0("flutter", "PhysicalShapeLayer::UpdateScene");
// Retained rendering: speedup by reusing a retained entity node if possible.
// When an entity node is reused, no paint layer is added to the frame so we
// won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(unique_id(), context.Matrix());
if (context.HasRetainedNode(key)) {
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
const scenic::EntityNode& retained_node = context.GetRetainedNode(key);
FML_DCHECK(context.top_entity());
FML_DCHECK(retained_node.session() == context.session());
context.top_entity()->entity_node().AddChild(retained_node);
return;
}
TRACE_EVENT_INSTANT0("flutter", "cache miss, creating");
// If we can't find an existing retained surface, create one.
SceneUpdateContext::Frame frame(context, frameRRect_, color(), elevation(),
this);
for (auto& layer : layers()) {
if (layer->needs_painting()) {
frame.AddPaintLayer(layer.get());
}
}
UpdateSceneChildren(context);
}
#endif // defined(OS_FUCHSIA)
void PhysicalShapeLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint");
FML_DCHECK(needs_painting());
+5 -14
View File
@@ -6,29 +6,24 @@
#define FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_
#include "flutter/flow/layers/elevated_container_layer.h"
#if defined(OS_FUCHSIA)
#include "flutter/flow/layers/fuchsia_system_composited_layer.h"
#endif
namespace flutter {
#if !defined(OS_FUCHSIA)
class PhysicalShapeLayerBase : public ElevatedContainerLayer {
public:
static bool can_system_composite() { return false; }
PhysicalShapeLayerBase(SkColor color, float elevation)
PhysicalShapeLayerBase(SkColor color, SkAlpha opacity, float elevation)
: ElevatedContainerLayer(elevation), color_(color) {}
void set_dimensions(SkRRect rrect) { }
void set_dimensions(SkRRect rrect) {}
SkColor color() const { return color_; }
SkAlpha opacity() const { return SK_AlphaOPAQUE; }
private:
SkColor color_;
};
#else
using PhysicalShapeLayerBase = FuchsiaSystemCompositedLayer;
#endif
class PhysicalShapeLayer : public PhysicalShapeLayerBase {
public:
@@ -42,7 +37,7 @@ class PhysicalShapeLayer : public PhysicalShapeLayerBase {
bool transparentOccluder,
SkScalar dpr);
PhysicalShapeLayer(SkColor color,
PhysicalShapeLayer(SkColor color,
SkColor shadow_color,
float elevation,
const SkPath& path,
@@ -51,10 +46,6 @@ PhysicalShapeLayer(SkColor color,
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext& context) const override;
#if defined(OS_FUCHSIA)
void UpdateScene(SceneUpdateContext& context) override;
#endif // defined(OS_FUCHSIA)
private:
SkColor shadow_color_;
SkPath path_;
@@ -124,24 +124,13 @@ TEST_F(PhysicalShapeLayerTest, ElevationSimple) {
SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path, Clip::none);
layer->Preroll(preroll_context(), SkMatrix());
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not do any painting there.
#if defined(OS_FUCHSIA)
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_TRUE(layer->needs_system_composite());
#else
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(layer->needs_system_composite());
#endif
EXPECT_EQ(layer->total_elevation(), initial_elevation);
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not use the direct |Paint()| path there.
#if !defined(OS_FUCHSIA)
SkPaint layer_paint;
layer_paint.setColor(SK_ColorGREEN);
layer_paint.setAntiAlias(true);
@@ -152,7 +141,6 @@ TEST_F(PhysicalShapeLayerTest, ElevationSimple) {
{MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}},
MockCanvas::DrawCall{
0, MockCanvas::DrawPathData{layer_path, layer_paint}}}));
#endif
}
TEST_F(PhysicalShapeLayerTest, ElevationComplex) {
@@ -184,27 +172,15 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) {
layers[0]->Preroll(preroll_context(), SkMatrix());
for (int i = 0; i < 4; i += 1) {
// On Fuchsia, the system compositor handles all elevated
// PhysicalShapeLayers and their shadows , so we do not do any painting
// there.
#if defined(OS_FUCHSIA)
EXPECT_EQ(layers[i]->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layers[i]->needs_painting());
EXPECT_TRUE(layers[i]->needs_system_composite());
#else
EXPECT_EQ(layers[i]->paint_bounds(),
(PhysicalShapeLayer::ComputeShadowBounds(
layer_path.getBounds(), initial_elevations[i],
1.0f /* pixel_ratio */)));
EXPECT_TRUE(layers[i]->needs_painting());
EXPECT_FALSE(layers[i]->needs_system_composite());
#endif
EXPECT_EQ(layers[i]->total_elevation(), total_elevations[i]);
}
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not use the direct |Paint()| path there.
#if !defined(OS_FUCHSIA)
SkPaint layer_paint;
layer_paint.setColor(SK_ColorBLACK);
layer_paint.setAntiAlias(true);
@@ -224,7 +200,6 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) {
MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}},
MockCanvas::DrawCall{
0, MockCanvas::DrawPathData{layer_path, layer_paint}}}));
#endif
}
} // namespace testing
+46 -46
View File
@@ -7,6 +7,7 @@
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/matrix_decomposition.h"
#include "flutter/fml/trace_event.h"
#include "include/core/SkColor.h"
namespace flutter {
@@ -59,18 +60,16 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node,
scenic::ShapeNode shape_node,
const SkRRect& rrect,
SkColor color,
float opacity,
const SkRect& paint_bounds,
std::vector<Layer*> paint_layers,
Layer* layer) {
// Frames always clip their children.
SetEntityNodeClipPlanes(entity_node, rrect.getBounds());
// TODO(SCN-1274): SetClip() will be deleted.
entity_node.SetClip(0u, true /* clip to self */);
// We don't need a shape if the frame is zero size.
if (rrect.isEmpty())
return;
SetEntityNodeClipPlanes(entity_node, rrect.getBounds());
// isEmpty should account for this, but we are adding these experimental
// checks to validate if this is the root cause for b/144933519.
if (std::isnan(rrect.width()) || std::isnan(rrect.height())) {
@@ -102,7 +101,9 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node,
// Check whether a solid color will suffice.
if (paint_layers.empty()) {
SetShapeColor(shape_node, color);
scenic::Material material(session_);
SetMaterialColor(material, color, opacity);
shape_node.SetMaterial(material);
return;
}
@@ -110,43 +111,38 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node,
const float scale_x = ScaleX();
const float scale_y = ScaleY();
// Apply a texture to the whole shape.
SetShapeTextureAndColor(shape_node, color, scale_x, scale_y, shape_bounds,
std::move(paint_layers), layer,
std::move(entity_node));
}
void SceneUpdateContext::SetShapeTextureAndColor(
scenic::ShapeNode& shape_node,
SkColor color,
SkScalar scale_x,
SkScalar scale_y,
const SkRect& paint_bounds,
std::vector<Layer*> paint_layers,
Layer* layer,
scenic::EntityNode entity_node) {
scenic::Image* image = GenerateImageIfNeeded(
color, scale_x, scale_y, paint_bounds, std::move(paint_layers), layer,
color, scale_x, scale_y, shape_bounds, std::move(paint_layers), layer,
std::move(entity_node));
if (image != nullptr) {
scenic::Material material(session_);
// The final shape's color is material_color * texture_color. The passed in
// material color was already used as a background when generating the
// texture, so set the model color to |SK_ColorWHITE| in order to allow
// using the texture's color unmodified.
SetMaterialColor(material, SK_ColorWHITE, opacity);
material.SetTexture(*image);
shape_node.SetMaterial(material);
return;
}
SetShapeColor(shape_node, color);
// No texture was needed, so apply a solid color to the whole shape.
if (SkColorGetA(color) != 0 && opacity != 0.0f) {
scenic::Material material(session_);
SetMaterialColor(material, color, opacity);
shape_node.SetMaterial(material);
return;
}
}
void SceneUpdateContext::SetShapeColor(scenic::ShapeNode& shape_node,
SkColor color) {
if (SkColorGetA(color) == 0)
return;
scenic::Material material(session_);
void SceneUpdateContext::SetMaterialColor(scenic::Material& material,
SkColor color,
float opacity) {
const SkAlpha color_alpha = (SkAlpha)(SkColorGetA(color) * opacity);
material.SetColor(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color),
SkColorGetA(color));
shape_node.SetMaterial(material);
color_alpha);
}
scenic::Image* SceneUpdateContext::GenerateImageIfNeeded(
@@ -235,6 +231,7 @@ SceneUpdateContext::Entity::Entity(SceneUpdateContext& context)
entity_node_(context.session()) {
if (previous_entity_)
previous_entity_->embedder_node().AddChild(entity_node_);
context.top_entity_ = this;
}
@@ -293,28 +290,37 @@ SceneUpdateContext::Transform::~Transform() {
context().top_scale_y_ = previous_scale_y_;
}
SceneUpdateContext::Shape::Shape(SceneUpdateContext& context)
: Entity(context), shape_node_(context.session()) {
entity_node().AddChild(shape_node_);
SceneUpdateContext::Clip::Clip(SceneUpdateContext& context,
const SkRect& shape_bounds)
: Entity(context) {
SetEntityNodeClipPlanes(entity_node(), shape_bounds);
}
SceneUpdateContext::Frame::Frame(SceneUpdateContext& context,
const SkRRect& rrect,
SkColor color,
float opacity,
float elevation,
Layer* layer)
: Shape(context),
: Entity(context),
opacity_node_(context.session()),
shape_node_(context.session()),
layer_(layer),
rrect_(rrect),
color_(color),
paint_bounds_(SkRect::MakeEmpty()),
layer_(layer) {
color_(color),
opacity_(opacity) {
entity_node().SetTranslation(0.f, 0.f, -elevation);
entity_node().AddChild(shape_node_);
entity_node().AddChild(opacity_node_);
opacity_node_.SetOpacity(opacity_);
}
SceneUpdateContext::Frame::~Frame() {
context().CreateFrame(std::move(entity_node()), std::move(shape_node()),
rrect_, color_, paint_bounds_, std::move(paint_layers_),
layer_);
context().CreateFrame(std::move(entity_node()), std::move(shape_node_),
rrect_, color_, opacity_, paint_bounds_,
std::move(paint_layers_), layer_);
}
void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) {
@@ -323,10 +329,4 @@ void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) {
paint_bounds_.join(layer->paint_bounds());
}
SceneUpdateContext::Clip::Clip(SceneUpdateContext& context,
const SkRect& shape_bounds)
: Entity(context) {
SetEntityNodeClipPlanes(entity_node(), shape_bounds);
}
} // namespace flutter
+18 -20
View File
@@ -89,25 +89,20 @@ class SceneUpdateContext {
float scale_x,
float scale_y,
float scale_z);
virtual ~Transform();
~Transform() override;
private:
float const previous_scale_x_;
float const previous_scale_y_;
};
class Shape : public Entity {
class Clip : public Entity {
public:
Shape(SceneUpdateContext& context);
virtual ~Shape() = default;
scenic::ShapeNode& shape_node() { return shape_node_; }
private:
scenic::ShapeNode shape_node_;
Clip(SceneUpdateContext& context, const SkRect& shape_bounds);
~Clip() override = default;
};
class Frame : public Shape {
class Frame : public Entity {
public:
// When layer is not nullptr, the frame is associated with a layer subtree
// rooted with that layer. The frame may then create a surface that will be
@@ -115,25 +110,25 @@ class SceneUpdateContext {
Frame(SceneUpdateContext& context,
const SkRRect& rrect,
SkColor color,
float opacity = 1.0f,
float elevation = 0.0f,
Layer* layer = nullptr);
virtual ~Frame();
~Frame() override;
scenic::ContainerNode& embedder_node() override { return opacity_node_; }
void AddPaintLayer(Layer* layer);
private:
const SkRRect rrect_;
SkColor const color_;
scenic::OpacityNodeHACK opacity_node_;
scenic::ShapeNode shape_node_;
std::vector<Layer*> paint_layers_;
SkRect paint_bounds_;
Layer* layer_;
};
class Clip : public Entity {
public:
Clip(SceneUpdateContext& context, const SkRect& shape_bounds);
~Clip() = default;
SkRRect rrect_;
SkRect paint_bounds_;
SkColor color_;
float opacity_;
};
SceneUpdateContext(scenic::Session* session,
@@ -206,6 +201,7 @@ class SceneUpdateContext {
scenic::ShapeNode shape_node,
const SkRRect& rrect,
SkColor color,
float opacity,
const SkRect& paint_bounds,
std::vector<Layer*> paint_layers,
Layer* layer);
@@ -217,7 +213,9 @@ class SceneUpdateContext {
std::vector<Layer*> paint_layers,
Layer* layer,
scenic::EntityNode entity_node);
void SetShapeColor(scenic::ShapeNode& shape_node, SkColor color);
void SetMaterialColor(scenic::Material& material,
SkColor color,
float opacity);
scenic::Image* GenerateImageIfNeeded(SkColor color,
SkScalar scale_x,
SkScalar scale_y,