Skip to content

Commit

Permalink
Use display list images. (flutter#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored and dnfield committed Apr 27, 2022
1 parent cbd14ba commit 9886da8
Show file tree
Hide file tree
Showing 20 changed files with 227 additions and 45 deletions.
8 changes: 8 additions & 0 deletions impeller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("tools/impeller.gni")

config("impeller_public_config") {
include_dirs = [ ".." ]

defines = []

if (impeller_supports_platform) {
defines += [ "IMPELLER_SUPPORTS_PLATFORM=1" ]
}
}

group("impeller") {
Expand Down
2 changes: 1 addition & 1 deletion impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ TEST_F(AiksTest, CanRenderImageRect) {
Canvas canvas;
Paint paint;
auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
auto source_rect = IRect::MakeSize(image->GetSize());
auto source_rect = Rect::MakeSize(Size(image->GetSize()));

// Render the bottom right quarter of the source image in a stretched rect.
source_rect.size.width /= 2;
Expand Down
14 changes: 9 additions & 5 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,22 +200,24 @@ void Canvas::DrawPicture(Picture picture) {

void Canvas::DrawImage(std::shared_ptr<Image> image,
Point offset,
Paint paint) {
Paint paint,
SamplerDescriptor sampler) {
if (!image) {
return;
}

const auto source = IRect::MakeSize(image->GetSize());
const auto source = Rect::MakeSize(Size(image->GetSize()));
const auto dest =
Rect::MakeXYWH(offset.x, offset.y, source.size.width, source.size.height);

DrawImageRect(image, source, dest, std::move(paint));
DrawImageRect(image, source, dest, std::move(paint), std::move(sampler));
}

void Canvas::DrawImageRect(std::shared_ptr<Image> image,
IRect source,
Rect source,
Rect dest,
Paint paint) {
Paint paint,
SamplerDescriptor sampler) {
if (!image || source.size.IsEmpty() || dest.size.IsEmpty()) {
return;
}
Expand All @@ -229,10 +231,12 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
auto contents = std::make_shared<TextureContents>();
contents->SetTexture(image->GetTexture());
contents->SetSourceRect(source);
contents->SetSamplerDescriptor(std::move(sampler));

Entity entity;
entity.SetPath(PathBuilder{}.AddRect(dest).TakePath());
entity.SetBlendMode(paint.blend_mode);
entity.SetStencilDepth(GetStencilDepth());
entity.SetContents(contents);
entity.SetTransformation(GetCurrentTransformation());

Expand Down
11 changes: 8 additions & 3 deletions impeller/aiks/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "impeller/geometry/path.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/vector.h"
#include "impeller/renderer/sampler_descriptor.h"
#include "impeller/typographer/glyph_atlas.h"
#include "impeller/typographer/text_frame.h"

Expand Down Expand Up @@ -65,12 +66,16 @@ class Canvas {

void DrawCircle(Point center, Scalar radius, Paint paint);

void DrawImage(std::shared_ptr<Image> image, Point offset, Paint paint);
void DrawImage(std::shared_ptr<Image> image,
Point offset,
Paint paint,
SamplerDescriptor sampler = {});

void DrawImageRect(std::shared_ptr<Image> image,
IRect source,
Rect source,
Rect dest,
Paint paint);
Paint paint,
SamplerDescriptor sampler = {});

void ClipPath(
Path path,
Expand Down
2 changes: 1 addition & 1 deletion impeller/aiks/paint_pass_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ std::shared_ptr<Contents> PaintPassDelegate::CreateContentsForSubpassTarget(
std::shared_ptr<Texture> target) {
auto contents = std::make_shared<TextureContents>();
contents->SetTexture(target);
contents->SetSourceRect(IRect::MakeSize(target->GetSize()));
contents->SetSourceRect(Rect::MakeSize(Size(target->GetSize())));
contents->SetOpacity(paint_.color.alpha);
return contents;
}
Expand Down
2 changes: 2 additions & 0 deletions impeller/display_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ impeller_component("display_list") {
sources = [
"display_list_dispatcher.cc",
"display_list_dispatcher.h",
"display_list_image_impeller.cc",
"display_list_image_impeller.h",
]

public_deps = [
Expand Down
70 changes: 57 additions & 13 deletions impeller/display_list/display_list_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -564,28 +564,71 @@ void DisplayListDispatcher::drawVertices(const sk_sp<SkVertices> vertices,
}

// |flutter::Dispatcher|
void DisplayListDispatcher::drawImage(const sk_sp<SkImage> image,
void DisplayListDispatcher::drawImage(const sk_sp<flutter::DlImage> image,
const SkPoint point,
const SkSamplingOptions& sampling,
bool render_with_attributes) {
// Needs https://github.com/flutter/flutter/issues/95434
UNIMPLEMENTED;
if (!image) {
return;
}

auto texture = image->impeller_texture();
if (!texture) {
return;
}

const auto size = texture->GetSize();
const auto src = SkRect::MakeWH(size.width, size.height);
const auto dest =
SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);

drawImageRect(
image, // image
src, // source rect
dest, // destination rect
sampling, // sampling options
render_with_attributes, // render with attributes
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint // constraint
);
}

static impeller::SamplerDescriptor ToSamplerDescriptor(
const SkSamplingOptions& options) {
impeller::SamplerDescriptor desc;
switch (options.filter) {
case SkFilterMode::kNearest:
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest;
desc.label = "Nearest Sampler";
break;
case SkFilterMode::kLinear:
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
desc.label = "Linear Sampler";
break;
default:
break;
}
return desc;
}

// |flutter::Dispatcher|
void DisplayListDispatcher::drawImageRect(
const sk_sp<SkImage> image,
const sk_sp<flutter::DlImage> image,
const SkRect& src,
const SkRect& dst,
const SkSamplingOptions& sampling,
bool render_with_attributes,
SkCanvas::SrcRectConstraint constraint) {
// Needs https://github.com/flutter/flutter/issues/95434
UNIMPLEMENTED;
canvas_.DrawImageRect(
std::make_shared<Image>(image->impeller_texture()), // image
ToRect(src), // source rect
ToRect(dst), // destination rect
paint_, // paint
ToSamplerDescriptor(sampling) // sampling
);
}

// |flutter::Dispatcher|
void DisplayListDispatcher::drawImageNine(const sk_sp<SkImage> image,
void DisplayListDispatcher::drawImageNine(const sk_sp<flutter::DlImage> image,
const SkIRect& center,
const SkRect& dst,
SkFilterMode filter,
Expand All @@ -595,17 +638,18 @@ void DisplayListDispatcher::drawImageNine(const sk_sp<SkImage> image,
}

// |flutter::Dispatcher|
void DisplayListDispatcher::drawImageLattice(const sk_sp<SkImage> image,
const SkCanvas::Lattice& lattice,
const SkRect& dst,
SkFilterMode filter,
bool render_with_attributes) {
void DisplayListDispatcher::drawImageLattice(
const sk_sp<flutter::DlImage> image,
const SkCanvas::Lattice& lattice,
const SkRect& dst,
SkFilterMode filter,
bool render_with_attributes) {
// Needs https://github.com/flutter/flutter/issues/95434
UNIMPLEMENTED;
}

// |flutter::Dispatcher|
void DisplayListDispatcher::drawAtlas(const sk_sp<SkImage> atlas,
void DisplayListDispatcher::drawAtlas(const sk_sp<flutter::DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
const SkColor colors[],
Expand Down
10 changes: 5 additions & 5 deletions impeller/display_list/display_list_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,35 +172,35 @@ class DisplayListDispatcher final : public flutter::Dispatcher {
flutter::DlBlendMode mode) override;

// |flutter::Dispatcher|
void drawImage(const sk_sp<SkImage> image,
void drawImage(const sk_sp<flutter::DlImage> image,
const SkPoint point,
const SkSamplingOptions& sampling,
bool render_with_attributes) override;

// |flutter::Dispatcher|
void drawImageRect(const sk_sp<SkImage> image,
void drawImageRect(const sk_sp<flutter::DlImage> image,
const SkRect& src,
const SkRect& dst,
const SkSamplingOptions& sampling,
bool render_with_attributes,
SkCanvas::SrcRectConstraint constraint) override;

// |flutter::Dispatcher|
void drawImageNine(const sk_sp<SkImage> image,
void drawImageNine(const sk_sp<flutter::DlImage> image,
const SkIRect& center,
const SkRect& dst,
SkFilterMode filter,
bool render_with_attributes) override;

// |flutter::Dispatcher|
void drawImageLattice(const sk_sp<SkImage> image,
void drawImageLattice(const sk_sp<flutter::DlImage> image,
const SkCanvas::Lattice& lattice,
const SkRect& dst,
SkFilterMode filter,
bool render_with_attributes) override;

// |flutter::Dispatcher|
void drawAtlas(const sk_sp<SkImage> atlas,
void drawAtlas(const sk_sp<flutter::DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
const SkColor colors[],
Expand Down
53 changes: 53 additions & 0 deletions impeller/display_list/display_list_image_impeller.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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 "impeller/display_list/display_list_image_impeller.h"

namespace impeller {

sk_sp<DlImageImpeller> DlImageImpeller::Make(std::shared_ptr<Texture> texture) {
if (!texture) {
return nullptr;
}
return sk_sp<DlImageImpeller>(new DlImageImpeller(std::move(texture)));
}

DlImageImpeller::DlImageImpeller(std::shared_ptr<Texture> texture)
: texture_(std::move(texture)) {}

// |DlImage|
DlImageImpeller::~DlImageImpeller() = default;

// |DlImage|
sk_sp<SkImage> DlImageImpeller::skia_image() const {
return nullptr;
};

// |DlImage|
std::shared_ptr<impeller::Texture> DlImageImpeller::impeller_texture() const {
return texture_;
}

// |DlImage|
bool DlImageImpeller::isTextureBacked() const {
// Impeller textures are always ... textures :/
return true;
}

// |DlImage|
SkISize DlImageImpeller::dimensions() const {
const auto size = texture_ ? texture_->GetSize() : ISize{};
return SkISize::Make(size.width, size.height);
}

// |DlImage|
size_t DlImageImpeller::GetApproximateByteSize() const {
auto size = sizeof(this);
if (texture_) {
size += texture_->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
}
return size;
}

} // namespace impeller
43 changes: 43 additions & 0 deletions impeller/display_list/display_list_image_impeller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.

#pragma once

#include "flutter/display_list/display_list_image.h"
#include "flutter/fml/macros.h"
#include "impeller/renderer/texture.h"

namespace impeller {

class DlImageImpeller final : public flutter::DlImage {
public:
static sk_sp<DlImageImpeller> Make(std::shared_ptr<Texture> texture);

// |DlImage|
~DlImageImpeller() override;

// |DlImage|
sk_sp<SkImage> skia_image() const override;

// |DlImage|
std::shared_ptr<impeller::Texture> impeller_texture() const override;

// |DlImage|
bool isTextureBacked() const override;

// |DlImage|
SkISize dimensions() const override;

// |DlImage|
size_t GetApproximateByteSize() const override;

private:
std::shared_ptr<Texture> texture_;

explicit DlImageImpeller(std::shared_ptr<Texture> texture);

FML_DISALLOW_COPY_AND_ASSIGN(DlImageImpeller);
};

} // namespace impeller
9 changes: 9 additions & 0 deletions impeller/display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "flutter/display_list/display_list_builder.h"
#include "flutter/testing/testing.h"
#include "impeller/display_list/display_list_image_impeller.h"
#include "impeller/display_list/display_list_playground.h"
#include "third_party/skia/include/core/SkPathBuilder.h"

Expand All @@ -27,6 +28,14 @@ TEST_F(DisplayListTest, CanDrawTextBlob) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_F(DisplayListTest, CanDrawImage) {
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
SkSamplingOptions{}, true);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_F(DisplayListTest, CapsAndJoins) {
flutter::DisplayListBuilder builder;

Expand Down
4 changes: 2 additions & 2 deletions impeller/entity/contents/filters/filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool FilterContents::Render(const ContentContext& renderer,

auto contents = std::make_shared<TextureContents>();
contents->SetTexture(snapshot.texture);
contents->SetSourceRect(IRect::MakeSize(snapshot.texture->GetSize()));
contents->SetSourceRect(Rect::MakeSize(Size(snapshot.texture->GetSize())));

Entity e;
e.SetPath(PathBuilder{}.AddRect(GetBounds(entity)).GetCurrentPath());
Expand Down Expand Up @@ -162,7 +162,7 @@ static std::optional<Contents::Snapshot> ResolveSnapshotForInput(
const ContentContext& renderer, RenderPass& pass) -> bool {
TextureContents contents;
contents.SetTexture(texture);
contents.SetSourceRect(IRect::MakeSize(texture->GetSize()));
contents.SetSourceRect(Rect::MakeSize(Size(texture->GetSize())));
Entity sub_entity;
sub_entity.SetPath(entity.GetPath());
sub_entity.SetBlendMode(Entity::BlendMode::kSource);
Expand Down
Loading

0 comments on commit 9886da8

Please sign in to comment.