skia2/gm/constcolorprocessor.cpp
Brian Salomon 649a3411f9 Add a separate draw function to GrRenderTargetContext for GrMeshDrawOp derived classes.
The first phase of deferring GrPipeline creation until flush will apply only to GrDrawOp subclasses that do not derive from GrMeshDrawOp. This change prepares for that by creating separate draw functions on GrRenderTargetContext for GrMeshDrawOp-derived ops. This is temporary and will incrementally be undone as pipeline-creation deferral rolls out to the GrMeshDrawOps in a later phase of this work.


Change-Id: I0f5b71fe913f3273cfe9e965f7d8bbe7f01ad0ef
Reviewed-on: https://skia-review.googlesource.com/9481
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
2017-03-09 19:26:13 +00:00

190 lines
7.1 KiB
C++

/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// This test only works with the GPU backend.
#include "gm.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "GrRenderTargetContextPriv.h"
#include "SkGr.h"
#include "SkGradientShader.h"
#include "effects/GrConstColorProcessor.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
namespace skiagm {
/**
* This GM directly exercises GrConstColorProcessor.
*/
class ConstColorProcessor : public GM {
public:
ConstColorProcessor() {
this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
}
protected:
SkString onShortName() override {
return SkString("const_color_processor");
}
SkISize onISize() override {
return SkISize::Make(kWidth, kHeight);
}
void onOnceBeforeDraw() override {
SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
SkShader::kClamp_TileMode);
}
void onDraw(SkCanvas* canvas) override {
GrRenderTargetContext* renderTargetContext =
canvas->internal_private_accessTopLayerRenderTargetContext();
if (!renderTargetContext) {
skiagm::GM::DrawGpuOnlyMessage(canvas);
return;
}
GrContext* context = canvas->getGrContext();
if (!context) {
return;
}
constexpr GrColor kColors[] = {
0xFFFFFFFF,
0xFFFF00FF,
0x80000000,
0x00000000,
};
constexpr SkColor kPaintColors[] = {
0xFFFFFFFF,
0xFFFF0000,
0x80FF0000,
0x00000000,
};
const char* kModeStrs[] {
"kIgnore",
"kModulateRGBA",
"kModulateA",
};
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
SkScalar y = kPad;
SkScalar x = kPad;
SkScalar maxW = 0;
for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
// translate by x,y for the canvas draws and the test target draws.
canvas->save();
canvas->translate(x, y);
const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
// rect to draw
SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
GrPaint grPaint;
SkPaint skPaint;
if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
skPaint.setShader(fShader);
} else {
skPaint.setColor(kPaintColors[paintType]);
}
SkAssertResult(SkPaintToGrPaint(context, renderTargetContext, skPaint,
viewMatrix, &grPaint));
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
GrColor4f color = GrColor4f::FromGrColor(kColors[procColor]);
sk_sp<GrFragmentProcessor> fp(GrConstColorProcessor::Make(color, mode));
grPaint.addColorFragmentProcessor(std::move(fp));
std::unique_ptr<GrMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
grPaint.getColor(), viewMatrix, renderRect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
// Draw labels for the input to the processor and the processor to the right of
// the test rect. The input label appears above the processor label.
SkPaint labelPaint;
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setAntiAlias(true);
labelPaint.setTextSize(10.f);
SkString inputLabel;
inputLabel.set("Input: ");
if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
inputLabel.append("gradient");
} else {
inputLabel.appendf("0x%08x", kPaintColors[paintType]);
}
SkString procLabel;
procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
SkRect inputLabelBounds;
// get the bounds of the text in order to position it
labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
&inputLabelBounds);
canvas->drawText(inputLabel.c_str(), inputLabel.size(),
renderRect.fRight + kPad,
-inputLabelBounds.fTop, labelPaint);
// update the bounds to reflect the offset we used to draw it.
inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
SkRect procLabelBounds;
labelPaint.measureText(procLabel.c_str(), procLabel.size(),
&procLabelBounds);
canvas->drawText(procLabel.c_str(), procLabel.size(),
renderRect.fRight + kPad,
inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
labelPaint);
procLabelBounds.offset(renderRect.fRight + kPad,
inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
labelPaint.setStrokeWidth(0);
labelPaint.setStyle(SkPaint::kStroke_Style);
canvas->drawRect(renderRect, labelPaint);
canvas->restore();
// update x and y for the next test case.
SkScalar height = renderRect.height();
SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
maxW = SkTMax(maxW, width);
y += height + kPad;
if (y + height > kHeight) {
y = kPad;
x += maxW + kPad;
maxW = 0;
}
}
}
}
}
private:
// Use this as a way of generating and input FP
sk_sp<SkShader> fShader;
static constexpr SkScalar kPad = 10.f;
static constexpr SkScalar kRectSize = 20.f;
static constexpr int kWidth = 820;
static constexpr int kHeight = 500;
typedef GM INHERITED;
};
DEF_GM(return new ConstColorProcessor;)
}
#endif