提交 9eb5df41 编写于 作者: A Adam Barth 提交者: GitHub

Add a way to hint the compositor (#2816)

The code that draws the picture knows more about the picture (and the future)
than we do. This patch gives them a way to hint us about what's going to
happen with the picture in the future.
上级 9546168c
......@@ -13,16 +13,13 @@ namespace flow {
// TODO(abarth): Make this configurable by developers.
const bool kDebugCheckerboardRasterizedLayers = false;
PictureLayer::PictureLayer() {
}
PictureLayer::PictureLayer() {}
PictureLayer::~PictureLayer() {
}
PictureLayer::~PictureLayer() {}
void PictureLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
image_ = context->raster_cache.GetPrerolledImage(
context->gr_context, picture_.get(), matrix);
context->gr_context, picture_.get(), matrix, is_complex_, will_change_);
context->child_paint_bounds =
picture_->cullRect().makeOffset(offset_.x(), offset_.y());
}
......
......@@ -15,9 +15,11 @@ class PictureLayer : public Layer {
~PictureLayer() override;
void set_offset(const SkPoint& offset) { offset_ = offset; }
void set_picture(sk_sp<SkPicture> picture) { picture_ = std::move(picture); }
void set_is_complex(bool value) { is_complex_ = value; }
void set_will_change(bool value) { will_change_ = value; }
SkPicture* picture() const { return picture_.get(); }
void Preroll(PrerollContext* frame, const SkMatrix& matrix) override;
......@@ -26,6 +28,8 @@ class PictureLayer : public Layer {
private:
SkPoint offset_;
sk_sp<SkPicture> picture_;
bool is_complex_ = false;
bool will_change_ = false;
// If we rasterized the picture separately, image_ holds the pixels.
sk_sp<SkImage> image_;
......
......@@ -27,30 +27,29 @@ static bool isWorthRasterizing(SkPicture* picture) {
#endif
RasterCache::RasterCache() {
}
RasterCache::RasterCache() {}
RasterCache::~RasterCache() {
}
RasterCache::~RasterCache() {}
RasterCache::Entry::Entry() {
physical_size.setEmpty();
}
RasterCache::Entry::~Entry() {
}
RasterCache::Entry::~Entry() {}
sk_sp<SkImage> RasterCache::GetPrerolledImage(GrContext* context,
SkPicture* picture,
const SkMatrix& ctm) {
SkPicture* picture,
const SkMatrix& ctm,
bool is_complex,
bool will_change) {
#if ENABLE_RASTER_CACHE
SkScalar scaleX = ctm.getScaleX();
SkScalar scaleY = ctm.getScaleY();
SkRect rect = picture->cullRect();
SkISize physical_size = SkISize::Make(rect.width() * scaleX,
rect.height() * scaleY);
SkISize physical_size =
SkISize::Make(rect.width() * scaleX, rect.height() * scaleY);
if (physical_size.isEmpty())
return nullptr;
......@@ -74,10 +73,10 @@ sk_sp<SkImage> RasterCache::GetPrerolledImage(GrContext* context,
// Saturate at the threshhold.
entry.access_count = kRasterThreshold;
if (!entry.image && isWorthRasterizing(picture)) {
TRACE_EVENT2("flutter", "Rasterize picture layer",
"width", physical_size.width(),
"height", physical_size.height());
if (!entry.image && !will_change &&
(is_complex || isWorthRasterizing(picture))) {
TRACE_EVENT2("flutter", "Rasterize picture layer", "width",
physical_size.width(), "height", physical_size.height());
SkImageInfo info = SkImageInfo::MakeN32Premul(physical_size);
sk_sp<SkSurface> surface =
SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
......
......@@ -21,8 +21,11 @@ class RasterCache {
RasterCache();
~RasterCache();
sk_sp<SkImage> GetPrerolledImage(
GrContext* context, SkPicture* picture, const SkMatrix& ctm);
sk_sp<SkImage> GetPrerolledImage(GrContext* context,
SkPicture* picture,
const SkMatrix& ctm,
bool is_complex,
bool will_change);
void SweepAfterFrame();
void Clear();
......
......@@ -175,10 +175,15 @@ class SceneBuilder extends NativeFieldWrapperClass2 {
/// Adds a [Picture] to the scene.
///
/// The picture is rasterized at the given offset.
void addPicture(Offset offset, Picture picture) {
_addPicture(offset.dx, offset.dy, picture);
void addPicture(Offset offset, Picture picture, { bool isComplex, bool willChange }) {
int hints = 0;
if (isComplex)
hints |= 1;
if (willChange)
hints |= 2;
_addPicture(offset.dx, offset.dy, picture, hints);
}
void _addPicture(double dx, double dy, Picture picture) native "SceneBuilder_addPicture";
void _addPicture(double dx, double dy, Picture picture, int hints) native "SceneBuilder_addPicture";
/// (mojo-only) Adds a scene rendered by another application to the scene for
/// this application.
......
......@@ -32,90 +32,81 @@ static void SceneBuilder_constructor(Dart_NativeArguments args) {
IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder);
#define FOR_EACH_BINDING(V) \
V(SceneBuilder, pushTransform) \
V(SceneBuilder, pushClipRect) \
V(SceneBuilder, pushClipRRect) \
V(SceneBuilder, pushClipPath) \
V(SceneBuilder, pushOpacity) \
V(SceneBuilder, pushColorFilter) \
V(SceneBuilder, pushBackdropFilter) \
V(SceneBuilder, pushShaderMask) \
V(SceneBuilder, pop) \
V(SceneBuilder, addPicture) \
V(SceneBuilder, addChildScene) \
V(SceneBuilder, addPerformanceOverlay) \
#define FOR_EACH_BINDING(V) \
V(SceneBuilder, pushTransform) \
V(SceneBuilder, pushClipRect) \
V(SceneBuilder, pushClipRRect) \
V(SceneBuilder, pushClipPath) \
V(SceneBuilder, pushOpacity) \
V(SceneBuilder, pushColorFilter) \
V(SceneBuilder, pushBackdropFilter) \
V(SceneBuilder, pushShaderMask) \
V(SceneBuilder, pop) \
V(SceneBuilder, addPicture) \
V(SceneBuilder, addChildScene) \
V(SceneBuilder, addPerformanceOverlay) \
V(SceneBuilder, setRasterizerTracingThreshold) \
V(SceneBuilder, build)
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
void SceneBuilder::RegisterNatives(DartLibraryNatives* natives) {
natives->Register({
{ "SceneBuilder_constructor", SceneBuilder_constructor, 1, true },
FOR_EACH_BINDING(DART_REGISTER_NATIVE)
});
natives->Register(
{{"SceneBuilder_constructor", SceneBuilder_constructor, 1, true},
FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
}
SceneBuilder::SceneBuilder()
: m_currentLayer(nullptr)
, m_currentRasterizerTracingThreshold(0)
{
}
: m_currentLayer(nullptr), m_currentRasterizerTracingThreshold(0) {}
SceneBuilder::~SceneBuilder()
{
}
SceneBuilder::~SceneBuilder() {}
void SceneBuilder::pushTransform(const Float64List& matrix4)
{
SkMatrix sk_matrix = ToSkMatrix(matrix4);
std::unique_ptr<flow::TransformLayer> layer(new flow::TransformLayer());
layer->set_transform(sk_matrix);
addLayer(std::move(layer));
void SceneBuilder::pushTransform(const Float64List& matrix4) {
SkMatrix sk_matrix = ToSkMatrix(matrix4);
std::unique_ptr<flow::TransformLayer> layer(new flow::TransformLayer());
layer->set_transform(sk_matrix);
addLayer(std::move(layer));
}
void SceneBuilder::pushClipRect(double left, double right, double top, double bottom)
{
std::unique_ptr<flow::ClipRectLayer> layer(new flow::ClipRectLayer());
layer->set_clip_rect(SkRect::MakeLTRB(left, top, right, bottom));
addLayer(std::move(layer));
void SceneBuilder::pushClipRect(double left,
double right,
double top,
double bottom) {
std::unique_ptr<flow::ClipRectLayer> layer(new flow::ClipRectLayer());
layer->set_clip_rect(SkRect::MakeLTRB(left, top, right, bottom));
addLayer(std::move(layer));
}
void SceneBuilder::pushClipRRect(const RRect& rrect)
{
std::unique_ptr<flow::ClipRRectLayer> layer(new flow::ClipRRectLayer());
layer->set_clip_rrect(rrect.sk_rrect);
addLayer(std::move(layer));
void SceneBuilder::pushClipRRect(const RRect& rrect) {
std::unique_ptr<flow::ClipRRectLayer> layer(new flow::ClipRRectLayer());
layer->set_clip_rrect(rrect.sk_rrect);
addLayer(std::move(layer));
}
void SceneBuilder::pushClipPath(const CanvasPath* path)
{
std::unique_ptr<flow::ClipPathLayer> layer(new flow::ClipPathLayer());
layer->set_clip_path(path->path());
addLayer(std::move(layer));
void SceneBuilder::pushClipPath(const CanvasPath* path) {
std::unique_ptr<flow::ClipPathLayer> layer(new flow::ClipPathLayer());
layer->set_clip_path(path->path());
addLayer(std::move(layer));
}
void SceneBuilder::pushOpacity(int alpha)
{
std::unique_ptr<flow::OpacityLayer> layer(new flow::OpacityLayer());
layer->set_alpha(alpha);
addLayer(std::move(layer));
void SceneBuilder::pushOpacity(int alpha) {
std::unique_ptr<flow::OpacityLayer> layer(new flow::OpacityLayer());
layer->set_alpha(alpha);
addLayer(std::move(layer));
}
void SceneBuilder::pushColorFilter(int color, int transferMode)
{
std::unique_ptr<flow::ColorFilterLayer> layer(new flow::ColorFilterLayer());
layer->set_color(static_cast<SkColor>(color));
layer->set_transfer_mode(static_cast<SkXfermode::Mode>(transferMode));
addLayer(std::move(layer));
void SceneBuilder::pushColorFilter(int color, int transferMode) {
std::unique_ptr<flow::ColorFilterLayer> layer(new flow::ColorFilterLayer());
layer->set_color(static_cast<SkColor>(color));
layer->set_transfer_mode(static_cast<SkXfermode::Mode>(transferMode));
addLayer(std::move(layer));
}
void SceneBuilder::pushBackdropFilter(ImageFilter* filter)
{
std::unique_ptr<flow::BackdropFilterLayer> layer(new flow::BackdropFilterLayer());
layer->set_filter(filter->filter());
addLayer(std::move(layer));
void SceneBuilder::pushBackdropFilter(ImageFilter* filter) {
std::unique_ptr<flow::BackdropFilterLayer> layer(
new flow::BackdropFilterLayer());
layer->set_filter(filter->filter());
addLayer(std::move(layer));
}
void SceneBuilder::pushShaderMask(Shader* shader,
......@@ -123,46 +114,48 @@ void SceneBuilder::pushShaderMask(Shader* shader,
double maskRectRight,
double maskRectTop,
double maskRectBottom,
int transferMode)
{
std::unique_ptr<flow::ShaderMaskLayer> layer(new flow::ShaderMaskLayer());
layer->set_shader(shader->shader());
layer->set_mask_rect(SkRect::MakeLTRB(maskRectLeft, maskRectTop, maskRectRight, maskRectBottom));
layer->set_transfer_mode(static_cast<SkXfermode::Mode>(transferMode));
addLayer(std::move(layer));
}
void SceneBuilder::addLayer(std::unique_ptr<flow::ContainerLayer> layer)
{
DCHECK(layer);
if (!m_rootLayer) {
DCHECK(!m_currentLayer);
m_rootLayer = std::move(layer);
m_currentLayer = m_rootLayer.get();
return;
}
if (!m_currentLayer)
return;
flow::ContainerLayer* newLayer = layer.get();
m_currentLayer->Add(std::move(layer));
m_currentLayer = newLayer;
}
void SceneBuilder::pop()
{
if (!m_currentLayer)
return;
m_currentLayer = m_currentLayer->parent();
}
void SceneBuilder::addPicture(double dx, double dy, Picture* picture)
{
if (!m_currentLayer)
return;
std::unique_ptr<flow::PictureLayer> layer(new flow::PictureLayer());
layer->set_offset(SkPoint::Make(dx, dy));
layer->set_picture(picture->picture());
m_currentLayer->Add(std::move(layer));
int transferMode) {
std::unique_ptr<flow::ShaderMaskLayer> layer(new flow::ShaderMaskLayer());
layer->set_shader(shader->shader());
layer->set_mask_rect(SkRect::MakeLTRB(maskRectLeft, maskRectTop,
maskRectRight, maskRectBottom));
layer->set_transfer_mode(static_cast<SkXfermode::Mode>(transferMode));
addLayer(std::move(layer));
}
void SceneBuilder::addLayer(std::unique_ptr<flow::ContainerLayer> layer) {
DCHECK(layer);
if (!m_rootLayer) {
DCHECK(!m_currentLayer);
m_rootLayer = std::move(layer);
m_currentLayer = m_rootLayer.get();
return;
}
if (!m_currentLayer)
return;
flow::ContainerLayer* newLayer = layer.get();
m_currentLayer->Add(std::move(layer));
m_currentLayer = newLayer;
}
void SceneBuilder::pop() {
if (!m_currentLayer)
return;
m_currentLayer = m_currentLayer->parent();
}
void SceneBuilder::addPicture(double dx,
double dy,
Picture* picture,
int hints) {
if (!m_currentLayer)
return;
std::unique_ptr<flow::PictureLayer> layer(new flow::PictureLayer());
layer->set_offset(SkPoint::Make(dx, dy));
layer->set_picture(picture->picture());
layer->set_is_complex(!!(hints & 1));
layer->set_will_change(!!(hints & 2));
m_currentLayer->Add(std::move(layer));
}
void SceneBuilder::addChildScene(double dx,
......@@ -171,44 +164,43 @@ void SceneBuilder::addChildScene(double dx,
int physicalWidth,
int physicalHeight,
uint32_t sceneToken) {
if (!m_currentLayer)
return;
std::unique_ptr<flow::ChildSceneLayer> layer(new flow::ChildSceneLayer());
layer->set_offset(SkPoint::Make(dx, dy));
layer->set_device_pixel_ratio(devicePixelRatio);
layer->set_physical_size(SkISize::Make(physicalWidth, physicalHeight));
mojo::gfx::composition::SceneTokenPtr token = mojo::gfx::composition::SceneToken::New();
token->value = sceneToken;
layer->set_scene_token(token.Pass());
m_currentLayer->Add(std::move(layer));
if (!m_currentLayer)
return;
std::unique_ptr<flow::ChildSceneLayer> layer(new flow::ChildSceneLayer());
layer->set_offset(SkPoint::Make(dx, dy));
layer->set_device_pixel_ratio(devicePixelRatio);
layer->set_physical_size(SkISize::Make(physicalWidth, physicalHeight));
mojo::gfx::composition::SceneTokenPtr token =
mojo::gfx::composition::SceneToken::New();
token->value = sceneToken;
layer->set_scene_token(token.Pass());
m_currentLayer->Add(std::move(layer));
}
void SceneBuilder::addPerformanceOverlay(uint64_t enabledOptions,
double left,
double right,
double top,
double bottom)
{
if (!m_currentLayer)
return;
std::unique_ptr<flow::PerformanceOverlayLayer> layer(new flow::PerformanceOverlayLayer(enabledOptions));
layer->set_paint_bounds(SkRect::MakeLTRB(left, top, right, bottom));
m_currentLayer->Add(std::move(layer));
double bottom) {
if (!m_currentLayer)
return;
std::unique_ptr<flow::PerformanceOverlayLayer> layer(
new flow::PerformanceOverlayLayer(enabledOptions));
layer->set_paint_bounds(SkRect::MakeLTRB(left, top, right, bottom));
m_currentLayer->Add(std::move(layer));
}
void SceneBuilder::setRasterizerTracingThreshold(uint32_t frameInterval)
{
m_currentRasterizerTracingThreshold = frameInterval;
void SceneBuilder::setRasterizerTracingThreshold(uint32_t frameInterval) {
m_currentRasterizerTracingThreshold = frameInterval;
}
scoped_refptr<Scene> SceneBuilder::build()
{
m_currentLayer = nullptr;
int32_t threshold = m_currentRasterizerTracingThreshold;
m_currentRasterizerTracingThreshold = 0;
scoped_refptr<Scene> scene = Scene::create(std::move(m_rootLayer), threshold);
ClearDartWrapper();
return std::move(scene);
scoped_refptr<Scene> SceneBuilder::build() {
m_currentLayer = nullptr;
int32_t threshold = m_currentRasterizerTracingThreshold;
m_currentRasterizerTracingThreshold = 0;
scoped_refptr<Scene> scene = Scene::create(std::move(m_rootLayer), threshold);
ClearDartWrapper();
return std::move(scene);
}
} // namespace blink
} // namespace blink
......@@ -21,57 +21,59 @@
namespace blink {
class SceneBuilder : public base::RefCountedThreadSafe<SceneBuilder>, public DartWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
static scoped_refptr<SceneBuilder> create() { return new SceneBuilder(); }
~SceneBuilder() override;
void pushTransform(const Float64List& matrix4);
void pushClipRect(double left, double right, double top, double bottom);
void pushClipRRect(const RRect& rrect);
void pushClipPath(const CanvasPath* path);
void pushOpacity(int alpha);
void pushColorFilter(int color, int transferMode);
void pushBackdropFilter(ImageFilter* filter);
void pushShaderMask(Shader* shader,
double maskRectLeft,
double maskRectRight,
double maskRectTop,
double maskRectBottom,
int transferMode);
void pop();
void addPerformanceOverlay(uint64_t enabledOptions,
double left,
double right,
double top,
double bottom);
void addPicture(double dx, double dy, Picture* picture);
void addChildScene(double dx,
double dy,
double devicePixelRatio,
int physicalWidth,
int physicalHeight,
uint32_t sceneToken);
void setRasterizerTracingThreshold(uint32_t frameInterval);
scoped_refptr<Scene> build();
static void RegisterNatives(DartLibraryNatives* natives);
private:
explicit SceneBuilder();
void addLayer(std::unique_ptr<flow::ContainerLayer> layer);
std::unique_ptr<flow::ContainerLayer> m_rootLayer;
flow::ContainerLayer* m_currentLayer;
int32_t m_currentRasterizerTracingThreshold;
class SceneBuilder : public base::RefCountedThreadSafe<SceneBuilder>,
public DartWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
static scoped_refptr<SceneBuilder> create() { return new SceneBuilder(); }
~SceneBuilder() override;
void pushTransform(const Float64List& matrix4);
void pushClipRect(double left, double right, double top, double bottom);
void pushClipRRect(const RRect& rrect);
void pushClipPath(const CanvasPath* path);
void pushOpacity(int alpha);
void pushColorFilter(int color, int transferMode);
void pushBackdropFilter(ImageFilter* filter);
void pushShaderMask(Shader* shader,
double maskRectLeft,
double maskRectRight,
double maskRectTop,
double maskRectBottom,
int transferMode);
void pop();
void addPerformanceOverlay(uint64_t enabledOptions,
double left,
double right,
double top,
double bottom);
void addPicture(double dx, double dy, Picture* picture, int hints);
void addChildScene(double dx,
double dy,
double devicePixelRatio,
int physicalWidth,
int physicalHeight,
uint32_t sceneToken);
void setRasterizerTracingThreshold(uint32_t frameInterval);
scoped_refptr<Scene> build();
static void RegisterNatives(DartLibraryNatives* natives);
private:
explicit SceneBuilder();
void addLayer(std::unique_ptr<flow::ContainerLayer> layer);
std::unique_ptr<flow::ContainerLayer> m_rootLayer;
flow::ContainerLayer* m_currentLayer;
int32_t m_currentRasterizerTracingThreshold;
};
} // namespace blink
} // namespace blink
#endif // FLUTTER_LIB_UI_COMPOSITING_SCENE_BUILDER_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册