Allow checkerboarding raster cache entries for debugging purposes (can be toggled from Dart). (#3200)
diff --git a/flow/BUILD.gn b/flow/BUILD.gn
index cf444fa..f5a309e 100644
--- a/flow/BUILD.gn
+++ b/flow/BUILD.gn
@@ -42,6 +42,7 @@
]
deps = [
+ "//flutter/common",
"//flutter/glue",
"//flutter/skia",
"//flutter/synchronization",
diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc
index c0262f0..9ed4b07 100644
--- a/flow/layers/layer_tree.cc
+++ b/flow/layers/layer_tree.cc
@@ -4,13 +4,16 @@
#include "flutter/flow/layers/layer_tree.h"
-#include "flutter/glue/trace_event.h"
#include "flutter/flow/layers/layer.h"
+#include "flutter/glue/trace_event.h"
namespace flow {
LayerTree::LayerTree()
- : frame_size_{}, scene_version_(0), rasterizer_tracing_threshold_(0) {}
+ : frame_size_{},
+ scene_version_(0),
+ rasterizer_tracing_threshold_(0),
+ checkerboard_raster_cache_images_(0) {}
LayerTree::~LayerTree() {}
diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h
index f1dfcdb..d8afe4b 100644
--- a/flow/layers/layer_tree.h
+++ b/flow/layers/layer_tree.h
@@ -66,13 +66,21 @@
return rasterizer_tracing_threshold_;
}
+ void set_checkerboard_raster_cache_images(bool checkerboard) {
+ checkerboard_raster_cache_images_ = checkerboard;
+ }
+
+ bool checkerboard_raster_cache_images() const {
+ return checkerboard_raster_cache_images_;
+ }
+
private:
SkISize frame_size_; // Physical pixels.
uint32_t scene_version_;
std::unique_ptr<Layer> root_layer_;
-
ftl::TimeDelta construction_time_;
uint32_t rasterizer_tracing_threshold_;
+ bool checkerboard_raster_cache_images_;
FTL_DISALLOW_COPY_AND_ASSIGN(LayerTree);
};
diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc
index 8fcbc3b..b010378 100644
--- a/flow/raster_cache.cc
+++ b/flow/raster_cache.cc
@@ -4,6 +4,9 @@
#include "flutter/flow/raster_cache.h"
+#include <vector>
+
+#include "flutter/common/threads.h"
#include "flutter/glue/trace_event.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -11,12 +14,8 @@
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"
-#define ENABLE_RASTER_CACHE 1
-
namespace flow {
-#if ENABLE_RASTER_CACHE
-
static const int kRasterThreshold = 3;
static bool isWorthRasterizing(SkPicture* picture) {
@@ -25,9 +24,43 @@
return picture->approximateOpCount() > 10;
}
-#endif
+static sk_sp<SkShader> CreateCheckerboardShader(SkColor c1,
+ SkColor c2,
+ int size) {
+ SkBitmap bm;
+ bm.allocN32Pixels(2 * size, 2 * size);
+ bm.eraseColor(c1);
+ bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2);
+ bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2);
+ return SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode);
+}
-RasterCache::RasterCache() {}
+static void DrawCheckerboard(SkCanvas* canvas,
+ SkColor c1,
+ SkColor c2,
+ int size) {
+ SkPaint paint;
+ paint.setShader(CreateCheckerboardShader(c1, c2, size));
+ canvas->drawPaint(paint);
+}
+
+static void DrawCheckerboard(SkCanvas* canvas, const SkRect& rect) {
+ // Draw a checkerboard
+ canvas->save();
+ canvas->clipRect(rect);
+ DrawCheckerboard(canvas, 0x4400FF00, 0x00000000, 12);
+ canvas->restore();
+
+ // Stroke the drawn area
+ SkPaint debugPaint;
+ debugPaint.setStrokeWidth(3);
+ debugPaint.setColor(SK_ColorRED);
+ debugPaint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect(rect, debugPaint);
+}
+
+RasterCache::RasterCache() : checkerboard_images_(false), weak_factory_(this) {}
RasterCache::~RasterCache() {}
@@ -42,7 +75,6 @@
const SkMatrix& ctm,
bool is_complex,
bool will_change) {
-#if ENABLE_RASTER_CACHE
SkScalar scaleX = ctm.getScaleX();
SkScalar scaleY = ctm.getScaleY();
@@ -86,15 +118,15 @@
canvas->scale(scaleX, scaleY);
canvas->translate(-rect.left(), -rect.top());
canvas->drawPicture(picture);
+ if (checkerboard_images_) {
+ DrawCheckerboard(canvas, rect);
+ }
entry.image = surface->makeImageSnapshot();
}
}
}
return entry.image;
-#else
- return nullptr;
-#endif
}
void RasterCache::SweepAfterFrame() {
@@ -115,4 +147,20 @@
cache_.clear();
}
+void RasterCache::SetCheckboardCacheImages(bool checkerboard) {
+ if (checkerboard_images_ == checkerboard) {
+ return;
+ }
+
+ checkerboard_images_ = checkerboard;
+
+ // Clear all existing entries so previously rasterized items (with or without
+ // a checkerboard) will be refreshed in subsequent passes.
+ blink::Threads::Gpu()->PostTask([self = weak_factory_.GetWeakPtr()]() {
+ if (self) {
+ self->Clear();
+ }
+ });
+}
+
} // namespace flow
diff --git a/flow/raster_cache.h b/flow/raster_cache.h
index 6c98840..13b08e8 100644
--- a/flow/raster_cache.h
+++ b/flow/raster_cache.h
@@ -10,6 +10,7 @@
#include "flutter/flow/instrumentation.h"
#include "lib/ftl/macros.h"
+#include "lib/ftl/memory/weak_ptr.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSize.h"
@@ -29,6 +30,8 @@
void Clear();
+ void SetCheckboardCacheImages(bool checkerboard);
+
private:
struct Entry {
Entry();
@@ -41,7 +44,10 @@
};
using Cache = std::unordered_map<uint32_t, Entry>;
+
Cache cache_;
+ bool checkerboard_images_;
+ ftl::WeakPtrFactory<RasterCache> weak_factory_;
FTL_DISALLOW_COPY_AND_ASSIGN(RasterCache);
};
diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc
index ab80b07..57d0902 100644
--- a/lib/ui/compositing/scene.cc
+++ b/lib/ui/compositing/scene.cc
@@ -4,9 +4,9 @@
#include "flutter/lib/ui/compositing/scene.h"
+#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
#include "lib/tonic/dart_binding_macros.h"
-#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_library_natives.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
@@ -20,16 +20,21 @@
DART_BIND_ALL(Scene, FOR_EACH_BINDING)
ftl::RefPtr<Scene> Scene::create(std::unique_ptr<flow::Layer> rootLayer,
- uint32_t rasterizerTracingThreshold) {
+ uint32_t rasterizerTracingThreshold,
+ bool checkerboardRasterCacheImages) {
return ftl::MakeRefCounted<Scene>(std::move(rootLayer),
- rasterizerTracingThreshold);
+ rasterizerTracingThreshold,
+ checkerboardRasterCacheImages);
}
Scene::Scene(std::unique_ptr<flow::Layer> rootLayer,
- uint32_t rasterizerTracingThreshold)
+ uint32_t rasterizerTracingThreshold,
+ bool checkerboardRasterCacheImages)
: m_layerTree(new flow::LayerTree()) {
m_layerTree->set_root_layer(std::move(rootLayer));
m_layerTree->set_rasterizer_tracing_threshold(rasterizerTracingThreshold);
+ m_layerTree->set_checkerboard_raster_cache_images(
+ checkerboardRasterCacheImages);
}
Scene::~Scene() {}
diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h
index a9c7eaf..815b763 100644
--- a/lib/ui/compositing/scene.h
+++ b/lib/ui/compositing/scene.h
@@ -26,7 +26,8 @@
public:
~Scene() override;
static ftl::RefPtr<Scene> create(std::unique_ptr<flow::Layer> rootLayer,
- uint32_t rasterizerTracingThreshold);
+ uint32_t rasterizerTracingThreshold,
+ bool checkerboardRasterCacheImages);
std::unique_ptr<flow::LayerTree> takeLayerTree();
@@ -36,7 +37,8 @@
private:
explicit Scene(std::unique_ptr<flow::Layer> rootLayer,
- uint32_t rasterizerTracingThreshold);
+ uint32_t rasterizerTracingThreshold,
+ bool checkerboardRasterCacheImages);
std::unique_ptr<flow::LayerTree> m_layerTree;
};
diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc
index 78a121a..2fb8ef5 100644
--- a/lib/ui/compositing/scene_builder.cc
+++ b/lib/ui/compositing/scene_builder.cc
@@ -36,20 +36,21 @@
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) \
- V(SceneBuilder, setRasterizerTracingThreshold) \
+#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, setCheckerboardRasterCacheImages) \
V(SceneBuilder, build)
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
@@ -61,7 +62,9 @@
}
SceneBuilder::SceneBuilder()
- : m_currentLayer(nullptr), m_currentRasterizerTracingThreshold(0) {
+ : m_currentLayer(nullptr),
+ m_currentRasterizerTracingThreshold(0),
+ m_checkerboardRasterCacheImages(false) {
m_cullRects.push(SkRect::MakeLargest());
}
@@ -230,11 +233,16 @@
m_currentRasterizerTracingThreshold = frameInterval;
}
+void SceneBuilder::setCheckerboardRasterCacheImages(bool checkerboard) {
+ m_checkerboardRasterCacheImages = checkerboard;
+}
+
ftl::RefPtr<Scene> SceneBuilder::build() {
m_currentLayer = nullptr;
int32_t threshold = m_currentRasterizerTracingThreshold;
m_currentRasterizerTracingThreshold = 0;
- ftl::RefPtr<Scene> scene = Scene::create(std::move(m_rootLayer), threshold);
+ ftl::RefPtr<Scene> scene = Scene::create(std::move(m_rootLayer), threshold,
+ m_checkerboardRasterCacheImages);
ClearDartWrapper();
return scene;
}
diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h
index 5d530f7..3c42808 100644
--- a/lib/ui/compositing/scene_builder.h
+++ b/lib/ui/compositing/scene_builder.h
@@ -5,9 +5,9 @@
#ifndef FLUTTER_LIB_UI_COMPOSITING_SCENE_BUILDER_H_
#define FLUTTER_LIB_UI_COMPOSITING_SCENE_BUILDER_H_
-#include <stack>
#include <stdint.h>
#include <memory>
+#include <stack>
#include "flutter/flow/layers/container_layer.h"
#include "flutter/lib/ui/compositing/scene.h"
@@ -63,18 +63,22 @@
void setRasterizerTracingThreshold(uint32_t frameInterval);
+ void setCheckerboardRasterCacheImages(bool checkerboard);
+
ftl::RefPtr<Scene> build();
static void RegisterNatives(tonic::DartLibraryNatives* natives);
private:
- explicit SceneBuilder();
+ SceneBuilder();
- void addLayer(std::unique_ptr<flow::ContainerLayer> layer, const SkRect& cullRect);
+ void addLayer(std::unique_ptr<flow::ContainerLayer> layer,
+ const SkRect& cullRect);
std::unique_ptr<flow::ContainerLayer> m_rootLayer;
flow::ContainerLayer* m_currentLayer;
int32_t m_currentRasterizerTracingThreshold;
+ bool m_checkerboardRasterCacheImages;
std::stack<SkRect> m_cullRects;
};