Flutter Engine
opacity_layer.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/flow/layers/opacity_layer.h"
6 
7 #include "flutter/fml/trace_event.h"
8 #include "third_party/skia/include/core/SkPaint.h"
9 
10 namespace flutter {
11 
12 OpacityLayer::OpacityLayer(SkAlpha alpha, const SkPoint& offset)
13  : alpha_(alpha), offset_(offset) {}
14 
15 void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
16  TRACE_EVENT0("flutter", "OpacityLayer::Preroll");
17  FML_DCHECK(!GetChildContainer()->layers().empty()); // We can't be a leaf.
18 
19  SkMatrix child_matrix = matrix;
20  child_matrix.postTranslate(offset_.fX, offset_.fY);
21 
22  // Similar to what's done in TransformLayer::Preroll, we have to apply the
23  // reverse transformation to the cull rect to properly cull child layers.
24  context->cull_rect = context->cull_rect.makeOffset(-offset_.fX, -offset_.fY);
25 
27  SkMatrix::Translate(offset_.fX, offset_.fY));
28  context->mutators_stack.PushOpacity(alpha_);
31  ContainerLayer::Preroll(context, child_matrix);
32  context->mutators_stack.Pop();
33  context->mutators_stack.Pop();
34 
35  {
36  set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY));
37 #ifndef SUPPORT_FRACTIONAL_TRANSLATION
38  child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
39 #endif
40  TryToPrepareRasterCache(context, GetCacheableChild(), child_matrix);
41  }
42 
43  // Restore cull_rect
44  context->cull_rect = context->cull_rect.makeOffset(offset_.fX, offset_.fY);
45 }
46 
47 void OpacityLayer::Paint(PaintContext& context) const {
48  TRACE_EVENT0("flutter", "OpacityLayer::Paint");
50 
51  SkPaint paint;
52  paint.setAlpha(alpha_);
53 
54  SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
55  context.internal_nodes_canvas->translate(offset_.fX, offset_.fY);
56 
57 #ifndef SUPPORT_FRACTIONAL_TRANSLATION
59  context.leaf_nodes_canvas->getTotalMatrix()));
60 #endif
61 
62  if (context.raster_cache &&
64  *context.leaf_nodes_canvas, &paint)) {
65  return;
66  }
67 
68  // Skia may clip the content with saveLayerBounds (although it's not a
69  // guaranteed clip). So we have to provide a big enough saveLayerBounds. To do
70  // so, we first remove the offset from paint bounds since it's already in the
71  // matrix. Then we round out the bounds.
72  //
73  // Note that the following lines are only accessible when the raster cache is
74  // not available (e.g., when we're using the software backend in golden
75  // tests).
76  SkRect saveLayerBounds;
77  paint_bounds()
78  .makeOffset(-offset_.fX, -offset_.fY)
79  .roundOut(&saveLayerBounds);
80 
81  Layer::AutoSaveLayer save_layer =
82  Layer::AutoSaveLayer::Create(context, saveLayerBounds, &paint);
83  PaintChildren(context);
84 }
85 
86 #if defined(LEGACY_FUCHSIA_EMBEDDER)
87 
88 void OpacityLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
89  float saved_alpha = context->alphaf();
90  context->set_alphaf(context->alphaf() * (alpha_ / 255.f));
91  ContainerLayer::UpdateScene(context);
92  context->set_alphaf(saved_alpha);
93 }
94 
95 #endif
96 
97 } // namespace flutter
void Paint(PaintContext &context) const override
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86
OpacityLayer(SkAlpha alpha, const SkPoint &offset)
void PushTransform(const SkMatrix &matrix)
const std::vector< std::shared_ptr< Layer > > & layers() const
static AutoSaveLayer Create(const PaintContext &paint_context, const SkRect &bounds, const SkPaint *paint)
Definition: layer.cc:96
void PushOpacity(const int &alpha)
Layer * GetCacheableChild() const
Returns the best choice for a Layer object that can be used in RasterCache operations to cache the ch...
const RasterCache * raster_cache
Definition: layer.h:122
ContainerLayer * GetChildContainer() const
Returns the ContainerLayer used to hold all of the children of the MergedContainerLayer. Note that this may not be the best layer to use for caching the children.
bool needs_painting() const
Definition: layer.h:174
bool Draw(const SkPicture &picture, SkCanvas &canvas) const
static AutoPrerollSaveLayerState Create(PrerollContext *preroll_context, bool save_layer_is_active=true, bool layer_itself_performs_readback=false)
Definition: layer.cc:43
const SkRect & paint_bounds() const
Definition: layer.h:166
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
SkCanvas * leaf_nodes_canvas
Definition: layer.h:116
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:170
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
SkCanvas * internal_nodes_canvas
Definition: layer.h:115
static SkMatrix GetIntegralTransCTM(const SkMatrix &ctm)
Snap the translation components of the matrix to integers.
Definition: raster_cache.h:115
MutatorsStack & mutators_stack
Definition: layer.h:47
static void TryToPrepareRasterCache(PrerollContext *context, Layer *layer, const SkMatrix &matrix)
void PaintChildren(PaintContext &context) const