From 74959a1471cd3b20e2dd79fc0c685e7205a25cd9 Mon Sep 17 00:00:00 2001 From: liyuqian Date: Thu, 16 Jun 2016 14:10:34 -0700 Subject: [PATCH] Use Offscreen Surface for Split Screen A dashed line is also added to split the screen. Currently, drawing images with sRGB seems to still have bugs. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2069653002 Review-Url: https://codereview.chromium.org/2069653002 --- tools/viewer/Viewer.cpp | 23 +++++++++++-- tools/viewer/sk_app/Window.cpp | 4 +++ tools/viewer/sk_app/Window.h | 4 +++ tools/viewer/sk_app/WindowContext.cpp | 33 ++++++++++++++----- tools/viewer/sk_app/WindowContext.h | 5 +++ .../android/RasterWindowContext_android.cpp | 2 +- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 9aec01f3ec..be80f5748b 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -14,10 +14,12 @@ #include "SkCanvas.h" #include "SkCommonFlags.h" +#include "SkDashPathEffect.h" #include "SkMetaData.h" #include "SkOSFile.h" #include "SkRandom.h" #include "SkStream.h" +#include "SkSurface.h" using namespace sk_app; @@ -371,9 +373,26 @@ void Viewer::drawSlide(SkCanvas* canvas, bool inSplitScreen) { canvas->concat(fDefaultMatrix); canvas->concat(computeMatrix()); - canvas->getMetaData().setBool(kImageColorXformMetaData, inSplitScreen); - fSlides[fCurrentSlide]->draw(canvas); + if (inSplitScreen) { + sk_sp offscreenSurface = fWindow->getOffscreenSurface(true); + fSlides[fCurrentSlide]->draw(offscreenSurface->getCanvas()); + sk_sp snapshot = offscreenSurface->makeImageSnapshot(); + canvas->drawImage(snapshot, 0, 0); + } else { + fSlides[fCurrentSlide]->draw(canvas); + } + canvas->restoreToCount(count); + + 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); + } } void Viewer::onPaint(SkCanvas* canvas) { diff --git a/tools/viewer/sk_app/Window.cpp b/tools/viewer/sk_app/Window.cpp index 7ec8baae36..068d1ce720 100644 --- a/tools/viewer/sk_app/Window.cpp +++ b/tools/viewer/sk_app/Window.cpp @@ -113,4 +113,8 @@ void Window::markInvalProcessed() { fIsContentInvalidated = false; } +sk_sp Window::getOffscreenSurface(bool forceSRGB) { + return fWindowContext->createOffscreenSurface(forceSRGB); +} + } // namespace sk_app diff --git a/tools/viewer/sk_app/Window.h b/tools/viewer/sk_app/Window.h index 8b1378a80f..f4d75cbe73 100644 --- a/tools/viewer/sk_app/Window.h +++ b/tools/viewer/sk_app/Window.h @@ -15,6 +15,7 @@ #include "SkJSONCPP.h" class SkCanvas; +class SkSurface; namespace sk_app { @@ -161,6 +162,9 @@ public: virtual const DisplayParams& getDisplayParams(); void setDisplayParams(const DisplayParams& params); + // This is just for the sRGB split screen + sk_sp getOffscreenSurface(bool forceSRGB); + protected: Window(); diff --git a/tools/viewer/sk_app/WindowContext.cpp b/tools/viewer/sk_app/WindowContext.cpp index ecac2cc004..ba04e7eace 100755 --- a/tools/viewer/sk_app/WindowContext.cpp +++ b/tools/viewer/sk_app/WindowContext.cpp @@ -21,24 +21,41 @@ namespace sk_app { +sk_sp WindowContext::createOffscreenSurface(bool forceSRGB) { + return createSurface(nullptr, 0, true, forceSRGB); +} + sk_sp WindowContext::createRenderSurface(sk_sp rt, int colorBits) { + return createSurface(rt, colorBits, false, false); +} + +sk_sp WindowContext::createSurface( + sk_sp rt, int colorBits, bool offscreen, bool forceSRGB) { auto flags = (fSurfaceProps.flags() & ~SkSurfaceProps::kGammaCorrect_Flag) | - (GrPixelConfigIsSRGB(fPixelConfig) ? SkSurfaceProps::kGammaCorrect_Flag : 0); + (GrPixelConfigIsSRGB(fPixelConfig) || forceSRGB ? + SkSurfaceProps::kGammaCorrect_Flag : 0); SkSurfaceProps props(flags, fSurfaceProps.pixelGeometry()); - if (!this->isGpuContext() || colorBits > 24 || + if (!this->isGpuContext() || colorBits > 24 || offscreen || kRGBA_F16_SkColorType == fDisplayParams.fColorType) { // If we're rendering to F16, we need an off-screen surface - the current render // target is most likely the wrong format. // // If we're rendering raster data or using a deep (10-bit or higher) surface, we probably // need an off-screen surface. 10-bit, in particular, has strange gamma behavior. - SkImageInfo info = SkImageInfo::Make(fWidth, fHeight, - fDisplayParams.fColorType, - kUnknown_SkAlphaType, - fDisplayParams.fColorSpace); - return SkSurface::MakeRenderTarget(fContext, SkBudgeted::kNo, info, - fDisplayParams.fMSAASampleCount, &props); + SkImageInfo info = SkImageInfo::Make( + fWidth, fHeight, + fDisplayParams.fColorType, + kPremul_SkAlphaType, + forceSRGB ? SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named) + : fDisplayParams.fColorSpace + ); + if (this->isGpuContext()) { + return SkSurface::MakeRenderTarget(fContext, SkBudgeted::kNo, info, + fDisplayParams.fMSAASampleCount, &props); + } else { + return SkSurface::MakeRaster(info, &props); + } } else { return SkSurface::MakeRenderTargetDirect(rt.get(), &props); } diff --git a/tools/viewer/sk_app/WindowContext.h b/tools/viewer/sk_app/WindowContext.h index fdd847445c..2c526a4bfe 100644 --- a/tools/viewer/sk_app/WindowContext.h +++ b/tools/viewer/sk_app/WindowContext.h @@ -44,6 +44,7 @@ public: virtual GrBackendContext getBackendContext() = 0; GrContext* getGrContext() const { return fContext; } + sk_sp createOffscreenSurface(bool sRGB); sk_sp createRenderSurface(sk_sp, int colorBits); void presentRenderSurface(sk_sp renderSurface, sk_sp rt, int colorBits); @@ -58,6 +59,10 @@ protected: DisplayParams fDisplayParams; GrPixelConfig fPixelConfig; SkSurfaceProps fSurfaceProps; + +private: + sk_sp createSurface( + sk_sp, int colorBits, bool offscreen, bool forceSRGB); }; } // namespace sk_app diff --git a/tools/viewer/sk_app/android/RasterWindowContext_android.cpp b/tools/viewer/sk_app/android/RasterWindowContext_android.cpp index a5f9a657fe..e2e2c0b16c 100644 --- a/tools/viewer/sk_app/android/RasterWindowContext_android.cpp +++ b/tools/viewer/sk_app/android/RasterWindowContext_android.cpp @@ -67,7 +67,7 @@ sk_sp RasterWindowContext_android::getBackbufferSurface() { const int bytePerPixel = fBuffer.format == WINDOW_FORMAT_RGB_565 ? 2 : 4; SkImageInfo info = SkImageInfo::Make(fWidth, fHeight, fDisplayParams.fColorType, - kOpaque_SkAlphaType, + kPremul_SkAlphaType, fDisplayParams.fColorSpace); fBackbufferSurface = SkSurface::MakeRasterDirect( info, fBuffer.bits, fBuffer.stride * bytePerPixel, nullptr);