Skip to content

Commit

Permalink
[embedder] embedder external view adopt DisplayListEmbedderViewSlice (f…
Browse files Browse the repository at this point in the history
…lutter#40578)

[embedder] embedder external view adopt DisplayListEmbedderViewSlice
  • Loading branch information
Chris Yang authored Apr 10, 2023
1 parent 0726328 commit de44501
Show file tree
Hide file tree
Showing 17 changed files with 1,146 additions and 26 deletions.
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
../../../flutter/shell/common/animator_unittests.cc
../../../flutter/shell/common/canvas_spy_unittests.cc
../../../flutter/shell/common/context_options_unittests.cc
../../../flutter/shell/common/dl_op_spy_unittests.cc
../../../flutter/shell/common/engine_unittests.cc
../../../flutter/shell/common/fixtures
../../../flutter/shell/common/input_events_unittests.cc
Expand Down
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2113,6 +2113,8 @@ ORIGIN: ../../../flutter/shell/common/display.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display_manager.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display_manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/dl_op_spy.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/dl_op_spy.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/engine.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/engine.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/pipeline.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -4701,6 +4703,8 @@ FILE: ../../../flutter/shell/common/display.cc
FILE: ../../../flutter/shell/common/display.h
FILE: ../../../flutter/shell/common/display_manager.cc
FILE: ../../../flutter/shell/common/display_manager.h
FILE: ../../../flutter/shell/common/dl_op_spy.cc
FILE: ../../../flutter/shell/common/dl_op_spy.h
FILE: ../../../flutter/shell/common/engine.cc
FILE: ../../../flutter/shell/common/engine.h
FILE: ../../../flutter/shell/common/pipeline.cc
Expand Down
3 changes: 1 addition & 2 deletions display_list/dl_blend_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace flutter {

/// A enum define the blend mode.
/// Blends are operators that take in two colors (source, destination) and
/// return a new color. Blends are operators that take in two colors (source,
/// destination) and return a new color. Many of these operate the same on all 4
/// return a new color. Many of these operate the same on all 4
/// components: red, green, blue, alpha. For these, we just document what
/// happens to one component, rather than naming each one separately. Different
/// color types might have different representations for color components:
Expand Down
12 changes: 12 additions & 0 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ void DisplayListEmbedderViewSlice::render_into(DlCanvas* canvas) {
canvas->DrawDisplayList(display_list_);
}

void DisplayListEmbedderViewSlice::dispatch(DlOpReceiver& receiver) {
display_list_->Dispatch(receiver);
}

bool DisplayListEmbedderViewSlice::is_empty() {
return display_list_->bounds().isEmpty();
}

bool DisplayListEmbedderViewSlice::recording_ended() {
return builder_ == nullptr;
}

void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame) {
frame->Submit();
Expand Down
3 changes: 3 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ class DisplayListEmbedderViewSlice : public EmbedderViewSlice {
std::list<SkRect> searchNonOverlappingDrawnRects(
const SkRect& query) const override;
void render_into(DlCanvas* canvas) override;
void dispatch(DlOpReceiver& receiver);
bool is_empty();
bool recording_ended();

private:
std::unique_ptr<DisplayListBuilder> builder_;
Expand Down
3 changes: 3 additions & 0 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ source_set("common") {
"display.h",
"display_manager.cc",
"display_manager.h",
"dl_op_spy.cc",
"dl_op_spy.h",
"engine.cc",
"engine.h",
"pipeline.cc",
Expand Down Expand Up @@ -287,6 +289,7 @@ if (enable_unittests) {
"animator_unittests.cc",
"canvas_spy_unittests.cc",
"context_options_unittests.cc",
"dl_op_spy_unittests.cc",
"engine_unittests.cc",
"input_events_unittests.cc",
"persistent_cache_unittests.cc",
Expand Down
138 changes: 138 additions & 0 deletions shell/common/dl_op_spy.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/common/dl_op_spy.h"

namespace flutter {

bool DlOpSpy::did_draw() {
return did_draw_;
}

void DlOpSpy::setColor(DlColor color) {
if (color.isTransparent()) {
will_draw_ = false;
} else {
will_draw_ = true;
}
}
void DlOpSpy::setColorSource(const DlColorSource* source) {
if (!source) {
return;
}
const DlColorColorSource* color_source = source->asColor();
if (color_source && color_source->color().isTransparent()) {
will_draw_ = false;
return;
}
will_draw_ = true;
}
void DlOpSpy::save() {}
void DlOpSpy::saveLayer(const SkRect* bounds,
const SaveLayerOptions options,
const DlImageFilter* backdrop) {}
void DlOpSpy::restore() {}
void DlOpSpy::drawColor(DlColor color, DlBlendMode mode) {
did_draw_ |= !color.isTransparent();
}
void DlOpSpy::drawPaint() {
did_draw_ |= will_draw_;
}
// TODO(cyanglaz): check whether the shape (line, rect, oval, etc) needs to be
// evaluated. https://github.com/flutter/flutter/issues/123803
void DlOpSpy::drawLine(const SkPoint& p0, const SkPoint& p1) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawRect(const SkRect& rect) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawOval(const SkRect& bounds) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawCircle(const SkPoint& center, SkScalar radius) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawRRect(const SkRRect& rrect) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawDRRect(const SkRRect& outer, const SkRRect& inner) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawPath(const SkPath& path) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawArc(const SkRect& oval_bounds,
SkScalar start_degrees,
SkScalar sweep_degrees,
bool use_center) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawPoints(PointMode mode,
uint32_t count,
const SkPoint points[]) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawVertices(const DlVertices* vertices, DlBlendMode mode) {
did_draw_ |= will_draw_;
}
// In theory, below drawImage methods can produce a transparent screen when a
// transparent image is provided. The operation of determine whether an image is
// transparent needs examine all the pixels in the image object, which is slow.
// Drawing a completely transparent image is not a valid use case, thus, such
// case is ignored.
void DlOpSpy::drawImage(const sk_sp<DlImage> image,
const SkPoint point,
DlImageSampling sampling,
bool render_with_attributes) {
did_draw_ = true;
}
void DlOpSpy::drawImageRect(const sk_sp<DlImage> image,
const SkRect& src,
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
SrcRectConstraint constraint) {
did_draw_ = true;
}
void DlOpSpy::drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
DlFilterMode filter,
bool render_with_attributes) {
did_draw_ = true;
}
void DlOpSpy::drawAtlas(const sk_sp<DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
const DlColor colors[],
int count,
DlBlendMode mode,
DlImageSampling sampling,
const SkRect* cull_rect,
bool render_with_attributes) {
did_draw_ = true;
}
void DlOpSpy::drawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity) {
if (did_draw_ || opacity == 0) {
return;
}
DlOpSpy receiver;
display_list->Dispatch(receiver);
did_draw_ |= receiver.did_draw();
}
void DlOpSpy::drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) {
did_draw_ |= will_draw_;
}
void DlOpSpy::drawShadow(const SkPath& path,
const DlColor color,
const SkScalar elevation,
bool transparent_occluder,
SkScalar dpr) {
did_draw_ |= !color.isTransparent();
}

} // namespace flutter
109 changes: 109 additions & 0 deletions shell/common/dl_op_spy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_
#define FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_

#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/display_list/utils/dl_receiver_utils.h"

namespace flutter {

//------------------------------------------------------------------------------
/// Receives to drawing commands of a DisplayListBuilder.
///
/// This is used to determine whether any non-transparent pixels will be drawn
/// on the canvas.
/// All the drawImage operations are considered drawing non-transparent pixels.
///
/// To use this class, dispatch the operations from DisplayList to a concrete
/// DlOpSpy object, and check the result of `did_draw` method.
///
/// ```
/// DlOpSpy dl_op_spy;
/// display_list.Dispatch(dl_op_spy);
/// bool did_draw = dl_op_spy.did_draw()
/// ```
///
class DlOpSpy final : public virtual DlOpReceiver,
private IgnoreAttributeDispatchHelper,
private IgnoreClipDispatchHelper,
private IgnoreTransformDispatchHelper {
public:
//----------------------------------------------------------------------------
/// @brief Returns true if any non transparent content has been drawn.
bool did_draw();

private:
void setColor(DlColor color) override;
void setColorSource(const DlColorSource* source) override;
void save() override;
void saveLayer(const SkRect* bounds,
const SaveLayerOptions options,
const DlImageFilter* backdrop) override;
void restore() override;
void drawColor(DlColor color, DlBlendMode mode) override;
void drawPaint() override;
void drawLine(const SkPoint& p0, const SkPoint& p1) override;
void drawRect(const SkRect& rect) override;
void drawOval(const SkRect& bounds) override;
void drawCircle(const SkPoint& center, SkScalar radius) override;
void drawRRect(const SkRRect& rrect) override;
void drawDRRect(const SkRRect& outer, const SkRRect& inner) override;
void drawPath(const SkPath& path) override;
void drawArc(const SkRect& oval_bounds,
SkScalar start_degrees,
SkScalar sweep_degrees,
bool use_center) override;
void drawPoints(PointMode mode,
uint32_t count,
const SkPoint points[]) override;
void drawVertices(const DlVertices* vertices, DlBlendMode mode) override;
void drawImage(const sk_sp<DlImage> image,
const SkPoint point,
DlImageSampling sampling,
bool render_with_attributes) override;
void drawImageRect(
const sk_sp<DlImage> image,
const SkRect& src,
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
SrcRectConstraint constraint = SrcRectConstraint::kFast) override;
void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
DlFilterMode filter,
bool render_with_attributes) override;
void drawAtlas(const sk_sp<DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
const DlColor colors[],
int count,
DlBlendMode mode,
DlImageSampling sampling,
const SkRect* cull_rect,
bool render_with_attributes) override;
void drawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity = SK_Scalar1) override;
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
void drawShadow(const SkPath& path,
const DlColor color,
const SkScalar elevation,
bool transparent_occluder,
SkScalar dpr) override;

// Indicates if the attributes are set to values that will modify the
// destination. For now, the test only checks if there is a non-transparent
// color set.
bool will_draw_ = true;

bool did_draw_ = false;
};

} // namespace flutter

#endif // FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_
Loading

0 comments on commit de44501

Please sign in to comment.