add a system for building SkCanvas wrappers for testing
This adds a way to build a wrapping canvas for testing that is allowed to manipulate the internal state of the canvas. It provides a way to add friends to SkCanvas without having to change SkCanvas. Change-Id: I40de8b236ba5acff45b3a8f7e440dcf6fa196fcf Reviewed-on: https://skia-review.googlesource.com/c/skia/+/524316 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
f3539b6c47
commit
3b238ceae9
@ -78,6 +78,7 @@ skia_utils_sources = [
|
||||
"$_src/utils/SkShadowUtils.cpp",
|
||||
"$_src/utils/SkShaperJSONWriter.cpp",
|
||||
"$_src/utils/SkShaperJSONWriter.h",
|
||||
"$_src/utils/SkTestCanvas.h",
|
||||
"$_src/utils/SkTextUtils.cpp",
|
||||
"$_src/utils/SkThreadUtils_pthread.cpp",
|
||||
"$_src/utils/SkThreadUtils_win.cpp",
|
||||
|
@ -2402,6 +2402,9 @@ private:
|
||||
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
|
||||
friend class SkOverdrawCanvas;
|
||||
friend class SkRasterHandleAllocator;
|
||||
template <typename Key>
|
||||
friend class SkTestCanvas;
|
||||
|
||||
protected:
|
||||
// For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
|
||||
SkCanvas(const SkIRect& bounds);
|
||||
|
@ -16,6 +16,12 @@
|
||||
class SK_API SkNWayCanvas : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
|
||||
public:
|
||||
SkNWayCanvas(int width, int height);
|
||||
|
||||
#if SK_SUPPORT_GPU && GR_TEST_UTILS
|
||||
// You can turn NWay canvas into a canvas a wrapper for a single canvas by passing the
|
||||
// canvas.
|
||||
SkNWayCanvas(SkCanvas*);
|
||||
#endif
|
||||
~SkNWayCanvas() override;
|
||||
|
||||
virtual void addCanvas(SkCanvas*);
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "include/private/chromium/GrSlug.h"
|
||||
#include "src/gpu/BaseDevice.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/utils/SkTestCanvas.h"
|
||||
#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
||||
# include "src/gpu/GrRenderTarget.h"
|
||||
# include "src/gpu/GrRenderTargetProxy.h"
|
||||
@ -2874,4 +2875,28 @@ SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> all
|
||||
return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if SK_SUPPORT_GPU && GR_TEST_UTILS
|
||||
SkTestCanvas<SkSlugTestKey>::SkTestCanvas(SkCanvas* convertCanvas)
|
||||
: SkNWayCanvas(convertCanvas)
|
||||
, fGPUCanvas(convertCanvas) { }
|
||||
|
||||
void SkTestCanvas<SkSlugTestKey>::onDrawGlyphRunList(
|
||||
const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
|
||||
SkRect bounds = glyphRunList.sourceBounds();
|
||||
if (this->internalQuickReject(bounds, paint)) {
|
||||
return;
|
||||
}
|
||||
auto layer = this->aboutToDraw(this, paint, &bounds);
|
||||
if (layer) {
|
||||
if (glyphRunList.hasRSXForm()) {
|
||||
fGPUCanvas->onDrawGlyphRunList(glyphRunList, layer->paint());
|
||||
} else {
|
||||
auto slug = fGPUCanvas->onConvertGlyphRunListToSlug(glyphRunList, layer->paint());
|
||||
fGPUCanvas->drawSlug(slug.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -8,14 +8,26 @@
|
||||
#include "include/core/SkShader.h"
|
||||
#include "include/utils/SkNWayCanvas.h"
|
||||
#include "src/core/SkCanvasPriv.h"
|
||||
#include "src/core/SkDevice.h"
|
||||
|
||||
SkNWayCanvas::SkNWayCanvas(int width, int height) : INHERITED(width, height) {}
|
||||
#if SK_SUPPORT_GPU && GR_TEST_UTILS
|
||||
SkNWayCanvas::SkNWayCanvas(SkCanvas* canvas) : INHERITED(sk_ref_sp(canvas->baseDevice())) {
|
||||
this->addCanvas(canvas);
|
||||
}
|
||||
#endif
|
||||
|
||||
SkNWayCanvas::~SkNWayCanvas() {
|
||||
this->removeAll();
|
||||
}
|
||||
|
||||
void SkNWayCanvas::addCanvas(SkCanvas* canvas) {
|
||||
if (!fList.isEmpty()) {
|
||||
// We are using the nway canvas as a wrapper for the originally added canvas, and the device
|
||||
// on the nway may contradict calls for the device on this canvas. So, to add a second
|
||||
// canvas, the devices on the first canvas, and the nway base device must be different.
|
||||
SkASSERT(fList[0]->baseDevice() != this->baseDevice());
|
||||
}
|
||||
if (canvas) {
|
||||
*fList.append() = canvas;
|
||||
}
|
||||
|
38
src/utils/SkTestCanvas.h
Normal file
38
src/utils/SkTestCanvas.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// SkTestCanvas is a simple way to make a testing canvas which is allowed to use private
|
||||
// facilities of SkCanvas without having to add a friend to SkCanvas.h.
|
||||
//
|
||||
// You create a Key (a simple empty struct) to make a template specialization class. You need to
|
||||
// make a key for each of the different Canvases you need. The implementations of the canvases
|
||||
// are in SkCanvas.cpp, which allows the use of helper classes.
|
||||
|
||||
#ifndef SkTestCanvas_DEFINED
|
||||
#define SkTestCanvas_DEFINED
|
||||
|
||||
#include "include/core/SkSize.h"
|
||||
#include "include/utils/SkNWayCanvas.h"
|
||||
#include "src/core/SkDevice.h"
|
||||
#include "src/core/SkGlyphRun.h"
|
||||
|
||||
// You can only make template specializations of SkTestCanvas.
|
||||
template <typename Key> class SkTestCanvas;
|
||||
|
||||
// A test canvas to test using slug rendering instead of text blob rendering.
|
||||
struct SkSlugTestKey {};
|
||||
template <>
|
||||
class SkTestCanvas<SkSlugTestKey> : public SkNWayCanvas {
|
||||
public:
|
||||
SkTestCanvas(SkCanvas* convertCanvas);
|
||||
void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
|
||||
|
||||
private:
|
||||
SkCanvas* fGPUCanvas;
|
||||
};
|
||||
|
||||
#endif // SkTestCanvas_DEFINED
|
Loading…
Reference in New Issue
Block a user