aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/viewer/Viewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/viewer/Viewer.cpp')
-rw-r--r--tools/viewer/Viewer.cpp121
1 files changed, 62 insertions, 59 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 0b93afc2b1..40486e72ac 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -18,6 +18,7 @@
#include "SkCommandLineFlags.h"
#include "SkDashPathEffect.h"
#include "SkGraphics.h"
+#include "SkImagePriv.h"
#include "SkMetaData.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
@@ -113,7 +114,6 @@ const char* kBackendStateName = "Backend";
const char* kSoftkeyStateName = "Softkey";
const char* kSoftkeyHint = "Please select a softkey";
const char* kFpsStateName = "FPS";
-const char* kSplitScreenStateName = "Split screen";
const char* kON = "ON";
const char* kOFF = "OFF";
const char* kRefreshStateName = "Refresh";
@@ -122,8 +122,9 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
: fCurrentMeasurement(0)
, fDisplayStats(false)
, fRefresh(false)
- , fSplitScreen(false)
, fBackendType(sk_app::Window::kNativeGL_BackendType)
+ , fColorType(kN32_SkColorType)
+ , fColorSpace(nullptr)
, fZoomCenterX(0.0f)
, fZoomCenterY(0.0f)
, fZoomLevel(0.0f)
@@ -162,13 +163,17 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
this->fDisplayStats = !this->fDisplayStats;
fWindow->inval();
});
- fCommands.addCommand('c', "Modes", "Toggle sRGB color mode", [this]() {
- DisplayParams params = fWindow->getDisplayParams();
- params.fColorSpace = (nullptr == params.fColorSpace)
- ? SkColorSpace::MakeSRGB() : nullptr;
- fWindow->setDisplayParams(params);
- this->updateTitle();
- fWindow->inval();
+ fCommands.addCommand('c', "Modes", "Cycle color mode", [this]() {
+ if (!fColorSpace) {
+ // Legacy -> sRGB
+ this->setColorMode(kN32_SkColorType, SkColorSpace::MakeSRGB());
+ } else if (kN32_SkColorType == fColorType) {
+ // sRGB -> F16 sRGB
+ this->setColorMode(kRGBA_F16_SkColorType, SkColorSpace::MakeSRGBLinear());
+ } else {
+ // F16 sRGB -> Legacy
+ this->setColorMode(kN32_SkColorType, nullptr);
+ }
});
fCommands.addCommand(Window::Key::kRight, "Right", "Navigation", "Next slide", [this]() {
int previousSlide = fCurrentSlide;
@@ -337,10 +342,13 @@ void Viewer::updateTitle() {
SkString title("Viewer: ");
title.append(fSlides[fCurrentSlide]->getName());
- // TODO: For now, any color-space on the window means sRGB
- if (fWindow->getDisplayParams().fColorSpace) {
- title.append(" sRGB");
+ title.appendf(" %s", sk_tool_utils::colortype_name(fColorType));
+
+ // TODO: Find a short string to describe the gamut of the color space?
+ if (fColorSpace) {
+ title.append(" ColorManaged");
}
+
title.append(kBackendTypeStrings[fBackendType]);
fWindow->setTitle(title.c_str());
}
@@ -422,56 +430,67 @@ SkMatrix Viewer::computeMatrix() {
return m;
}
-void Viewer::drawSlide(SkCanvas* canvas, bool inSplitScreen) {
- SkASSERT(!inSplitScreen || fWindow->supportsContentRect());
+void Viewer::setColorMode(SkColorType colorType, sk_sp<SkColorSpace> colorSpace) {
+ fColorType = colorType;
+ fColorSpace = std::move(colorSpace);
- int count = canvas->save();
+ // When we're in color managed mode, we tag our window surface as sRGB. If we've switched into
+ // or out of legacy mode, we need to update our window configuration.
+ DisplayParams params = fWindow->getDisplayParams();
+ if (SkToBool(fColorSpace) != SkToBool(params.fColorSpace)) {
+ params.fColorSpace = fColorSpace ? SkColorSpace::MakeSRGB() : nullptr;
+ fWindow->setDisplayParams(params);
+ }
+ this->updateTitle();
+ fWindow->inval();
+}
+
+void Viewer::drawSlide(SkCanvas* canvas) {
+ int count = canvas->save();
if (fWindow->supportsContentRect()) {
SkRect contentRect = fWindow->getContentRect();
- // If inSplitScreen, translate the image half screen to the right.
- // Thus we have two copies of the image on each half of the screen.
- contentRect.fLeft +=
- inSplitScreen ? (contentRect.fRight - contentRect.fLeft) * 0.5f : 0.0f;
canvas->clipRect(contentRect);
canvas->translate(contentRect.fLeft, contentRect.fTop);
}
- canvas->clear(SK_ColorWHITE);
- canvas->concat(fDefaultMatrix);
- canvas->concat(computeMatrix());
+ // By default, we render directly into the window's surface/canvas
+ SkCanvas* slideCanvas = canvas;
- if (inSplitScreen) {
- sk_sp<SkSurface> offscreenSurface = fWindow->getOffscreenSurface(true);
- offscreenSurface->getCanvas()->getMetaData().setBool(kImageColorXformMetaData, true);
- fSlides[fCurrentSlide]->draw(offscreenSurface->getCanvas());
- sk_sp<SkImage> snapshot = offscreenSurface->makeImageSnapshot();
- canvas->drawImage(snapshot, 0, 0);
- } else {
- fSlides[fCurrentSlide]->draw(canvas);
+ // ... but if we're in F16, or the gamut isn't sRGB, we need to render offscreen
+ sk_sp<SkSurface> offscreenSurface = nullptr;
+ if (kRGBA_F16_SkColorType == fColorType || fColorSpace != SkColorSpace::MakeSRGB()) {
+ SkImageInfo info = SkImageInfo::Make(fWindow->width(), fWindow->height(), fColorType,
+ kPremul_SkAlphaType, fColorSpace);
+ offscreenSurface = canvas->makeSurface(info);
+ slideCanvas = offscreenSurface->getCanvas();
}
- canvas->restoreToCount(count);
+ slideCanvas->clear(SK_ColorWHITE);
+ slideCanvas->concat(fDefaultMatrix);
+ slideCanvas->concat(computeMatrix());
- if (inSplitScreen) {
- // Draw split line
- SkPaint paint;
- SkScalar intervals[] = {10.0f, 5.0f};
- paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f));
- SkRect contentRect = fWindow->getContentRect();
- SkScalar middleX = (contentRect.fLeft + contentRect.fRight) * 0.5f;
- canvas->drawLine(middleX, contentRect.fTop, middleX, contentRect.fBottom, paint);
+ fSlides[fCurrentSlide]->draw(slideCanvas);
+
+ // If we rendered offscreen, snap an image and push the results to the window's canvas
+ if (offscreenSurface) {
+ auto slideImage = offscreenSurface->makeImageSnapshot();
+
+ // Tag the image with the sRGB gamut, so no further color space conversion happens
+ sk_sp<SkColorSpace> cs = (kRGBA_F16_SkColorType == fColorType)
+ ? SkColorSpace::MakeSRGBLinear() : SkColorSpace::MakeSRGB();
+ auto retaggedImage = SkImageMakeRasterCopyAndAssignColorSpace(slideImage.get(), cs.get());
+ canvas->drawImage(retaggedImage, 0, 0);
}
+
+ canvas->restoreToCount(count);
}
void Viewer::onPaint(SkCanvas* canvas) {
// Record measurements
double startTime = SkTime::GetMSecs();
- drawSlide(canvas, false);
- if (fSplitScreen && fWindow->supportsContentRect()) {
- drawSlide(canvas, true);
- }
+ drawSlide(canvas);
if (fDisplayStats) {
drawStats(canvas);
@@ -600,20 +619,11 @@ void Viewer::updateUIState() {
fpsState[kValue] = SkStringPrintf("%8.3lf ms", measurement).c_str();
fpsState[kOptions] = Json::Value(Json::arrayValue);
- // Split screen state
- Json::Value splitScreenState(Json::objectValue);
- splitScreenState[kName] = kSplitScreenStateName;
- splitScreenState[kValue] = fSplitScreen ? kON : kOFF;
- splitScreenState[kOptions] = Json::Value(Json::arrayValue);
- splitScreenState[kOptions].append(kON);
- splitScreenState[kOptions].append(kOFF);
-
Json::Value state(Json::arrayValue);
state.append(slideState);
state.append(backendState);
state.append(softkeyState);
state.append(fpsState);
- state.append(splitScreenState);
fWindow->setUIState(state);
}
@@ -656,13 +666,6 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
fCommands.onSoftkey(stateValue);
updateUIState(); // This is still needed to reset the value to kSoftkeyHint
}
- } else if (stateName.equals(kSplitScreenStateName)) {
- bool newSplitScreen = stateValue.equals(kON);
- if (newSplitScreen != fSplitScreen) {
- fSplitScreen = newSplitScreen;
- fWindow->inval();
- updateUIState();
- }
} else if (stateName.equals(kRefreshStateName)) {
// This state is actually NOT in the UI state.
// We use this to allow Android to quickly set bool fRefresh.