blob: 4d2efdf367842ed826ba452499603d8cd76e8b5b [file] [log] [blame] [edit]
// 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 FLOW_TESTING_MOCK_LAYER_H_
#define FLOW_TESTING_MOCK_LAYER_H_
#include <functional>
#include <memory>
#include "flutter/flow/diff_context.h"
#include "flutter/flow/layers/cacheable_layer.h"
#include "flutter/flow/layers/container_layer.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/layers/layer_raster_cache_item.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/flow/raster_cache_item.h"
namespace flutter {
namespace testing {
// Mock implementation of the |Layer| interface that does nothing but paint
// the specified |path| into the canvas. It records the |PrerollContext| and
// |PaintContext| data passed in by its parent |Layer|, so the test can later
// verify the data against expected values.
class MockLayer : public Layer {
public:
explicit MockLayer(const SkPath& path, DlPaint paint = DlPaint());
static std::shared_ptr<MockLayer> Make(SkPath path,
DlPaint paint = DlPaint()) {
return std::make_shared<MockLayer>(path, paint);
}
static std::shared_ptr<MockLayer> MakeOpacityCompatible(SkPath path) {
auto mock_layer = std::make_shared<MockLayer>(path, DlPaint());
mock_layer->set_fake_opacity_compatible(true);
return mock_layer;
}
void Preroll(PrerollContext* context) override;
void Paint(PaintContext& context) const override;
const MutatorsStack& parent_mutators() { return parent_mutators_; }
const SkMatrix& parent_matrix() { return parent_matrix_; }
const SkRect& parent_cull_rect() { return parent_cull_rect_; }
bool IsReplacing(DiffContext* context, const Layer* layer) const override;
void Diff(DiffContext* context, const Layer* old_layer) override;
const MockLayer* as_mock_layer() const override { return this; }
bool parent_has_platform_view() {
return mock_flags_ & kParentHasPlatformView;
}
bool parent_has_texture_layer() {
return mock_flags_ & kParentHasTextureLayer;
}
bool fake_has_platform_view() { return mock_flags_ & kFakeHasPlatformView; }
bool fake_reads_surface() { return mock_flags_ & kFakeReadsSurface; }
bool fake_opacity_compatible() {
return mock_flags_ & kFakeOpacityCompatible;
}
bool fake_has_texture_layer() { return mock_flags_ & kFakeHasTextureLayer; }
MockLayer& set_parent_has_platform_view(bool flag) {
flag ? (mock_flags_ |= kParentHasPlatformView)
: (mock_flags_ &= ~(kParentHasPlatformView));
return *this;
}
MockLayer& set_parent_has_texture_layer(bool flag) {
flag ? (mock_flags_ |= kParentHasTextureLayer)
: (mock_flags_ &= ~(kParentHasTextureLayer));
return *this;
}
MockLayer& set_fake_has_platform_view(bool flag) {
flag ? (mock_flags_ |= kFakeHasPlatformView)
: (mock_flags_ &= ~(kFakeHasPlatformView));
return *this;
}
MockLayer& set_fake_reads_surface(bool flag) {
flag ? (mock_flags_ |= kFakeReadsSurface)
: (mock_flags_ &= ~(kFakeReadsSurface));
return *this;
}
MockLayer& set_fake_opacity_compatible(bool flag) {
flag ? (mock_flags_ |= kFakeOpacityCompatible)
: (mock_flags_ &= ~(kFakeOpacityCompatible));
return *this;
}
MockLayer& set_fake_has_texture_layer(bool flag) {
flag ? (mock_flags_ |= kFakeHasTextureLayer)
: (mock_flags_ &= ~(kFakeHasTextureLayer));
return *this;
}
void set_expected_paint_matrix(const SkMatrix& matrix) {
expected_paint_matrix_ = matrix;
}
private:
MutatorsStack parent_mutators_;
SkMatrix parent_matrix_;
SkRect parent_cull_rect_ = SkRect::MakeEmpty();
SkPath fake_paint_path_;
DlPaint fake_paint_;
std::optional<SkMatrix> expected_paint_matrix_;
static constexpr int kParentHasPlatformView = 1 << 0;
static constexpr int kParentHasTextureLayer = 1 << 1;
static constexpr int kFakeHasPlatformView = 1 << 2;
static constexpr int kFakeReadsSurface = 1 << 3;
static constexpr int kFakeOpacityCompatible = 1 << 4;
static constexpr int kFakeHasTextureLayer = 1 << 5;
int mock_flags_ = 0;
FML_DISALLOW_COPY_AND_ASSIGN(MockLayer);
};
class MockCacheableContainerLayer : public CacheableContainerLayer {
public:
// if render more than 3 frames, try to cache itself.
// if less 3 frames, cache his children
static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOrChildren() {
return std::make_shared<MockCacheableContainerLayer>(true);
}
// if render more than 3 frames, try to cache itself.
// if less 3 frames, cache nothing
static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOnly() {
return std::make_shared<MockCacheableContainerLayer>();
}
void Preroll(PrerollContext* context) override;
explicit MockCacheableContainerLayer(bool cache_children = false)
: CacheableContainerLayer(3, cache_children) {}
};
class MockLayerCacheableItem : public LayerRasterCacheItem {
public:
using LayerRasterCacheItem::LayerRasterCacheItem;
};
class MockCacheableLayer : public MockLayer {
public:
explicit MockCacheableLayer(SkPath path,
DlPaint paint = DlPaint(),
int render_limit = 3)
: MockLayer(path, paint) {
raster_cache_item_ =
std::make_unique<MockLayerCacheableItem>(this, render_limit);
}
const LayerRasterCacheItem* raster_cache_item() const {
return raster_cache_item_.get();
}
void Preroll(PrerollContext* context) override;
private:
std::unique_ptr<LayerRasterCacheItem> raster_cache_item_;
};
} // namespace testing
} // namespace flutter
#endif // FLOW_TESTING_MOCK_LAYER_H_