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
This commit is contained in:
liyuqian 2016-06-16 14:10:34 -07:00 committed by Commit bot
parent 6dc3af4499
commit 74959a1471
6 changed files with 60 additions and 11 deletions

View File

@ -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<SkSurface> offscreenSurface = fWindow->getOffscreenSurface(true);
fSlides[fCurrentSlide]->draw(offscreenSurface->getCanvas());
sk_sp<SkImage> 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) {

View File

@ -113,4 +113,8 @@ void Window::markInvalProcessed() {
fIsContentInvalidated = false;
}
sk_sp<SkSurface> Window::getOffscreenSurface(bool forceSRGB) {
return fWindowContext->createOffscreenSurface(forceSRGB);
}
} // namespace sk_app

View File

@ -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<SkSurface> getOffscreenSurface(bool forceSRGB);
protected:
Window();

View File

@ -21,24 +21,41 @@
namespace sk_app {
sk_sp<SkSurface> WindowContext::createOffscreenSurface(bool forceSRGB) {
return createSurface(nullptr, 0, true, forceSRGB);
}
sk_sp<SkSurface> WindowContext::createRenderSurface(sk_sp<GrRenderTarget> rt, int colorBits) {
return createSurface(rt, colorBits, false, false);
}
sk_sp<SkSurface> WindowContext::createSurface(
sk_sp<GrRenderTarget> 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);
}

View File

@ -44,6 +44,7 @@ public:
virtual GrBackendContext getBackendContext() = 0;
GrContext* getGrContext() const { return fContext; }
sk_sp<SkSurface> createOffscreenSurface(bool sRGB);
sk_sp<SkSurface> createRenderSurface(sk_sp<GrRenderTarget>, int colorBits);
void presentRenderSurface(sk_sp<SkSurface> renderSurface, sk_sp<GrRenderTarget> rt,
int colorBits);
@ -58,6 +59,10 @@ protected:
DisplayParams fDisplayParams;
GrPixelConfig fPixelConfig;
SkSurfaceProps fSurfaceProps;
private:
sk_sp<SkSurface> createSurface(
sk_sp<GrRenderTarget>, int colorBits, bool offscreen, bool forceSRGB);
};
} // namespace sk_app

View File

@ -67,7 +67,7 @@ sk_sp<SkSurface> 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);