diff options
Diffstat (limited to 'tools/viewer/Viewer.cpp')
-rw-r--r-- | tools/viewer/Viewer.cpp | 121 |
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. |