Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2107,6 +2107,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 @@ -4689,6 +4691,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