Chromium Code Reviews| Index: tools/viewer/sk_app/GLWindowContext.cpp |
| diff --git a/tools/viewer/sk_app/GLWindowContext.cpp b/tools/viewer/sk_app/GLWindowContext.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..01e191f01f3520ebedf24a8e1c6c316fa6573694 |
| --- /dev/null |
| +++ b/tools/viewer/sk_app/GLWindowContext.cpp |
| @@ -0,0 +1,153 @@ |
| + |
| +/* |
| + * Copyright 2015 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "GrContext.h" |
| +#include "SkSurface.h" |
| +#include "GLWindowContext.h" |
| + |
| +#include "gl/GrGLDefines.h" |
| + |
| +#include "gl/GrGLUtil.h" |
| +#include "GrRenderTarget.h" |
| +#include "GrContext.h" |
| + |
| +#include "SkCanvas.h" |
| +#include "SkImage_Base.h" |
| + |
| +namespace sk_app { |
| + |
| +GLWindowContext::GLWindowContext(void* platformData, const DisplayParams& params) |
| + : WindowContext() |
| + , fBackendContext(nullptr) |
| + , fRenderTarget(nullptr) |
| + , fBackbuffer(nullptr) { |
| +} |
| + |
| +void GLWindowContext::initializeContext(void* platformData, const DisplayParams& params) { |
| + this->onInitializeContext(platformData, params); |
| + |
| + fDisplayParams = params; |
| + |
| + SkAutoTUnref<const GrGLInterface> glInterface; |
| + glInterface.reset(GrGLCreateNativeInterface()); |
| + fBackendContext.reset(GrGLInterfaceRemoveNVPR(glInterface.get())); |
| + |
| + SkASSERT(nullptr == fContext); |
| + fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fBackendContext.get()); |
| +} |
| + |
| +void GLWindowContext::destroyContext() { |
| + fBackbuffer.reset(nullptr); |
| + fRenderTarget.reset(nullptr); |
| + |
| + if (fContext) { |
| + // in case we have outstanding refs to this guy (lua?) |
| + fContext->abandonContext(); |
| + fContext->unref(); |
| + fContext = nullptr; |
| + } |
| + |
| + fBackendContext.reset(nullptr); |
| + |
| + this->onDestroyContext(); |
| +} |
| + |
| +sk_sp<SkSurface> GLWindowContext::getBackbufferSurface() { |
| + if (nullptr == fBackbuffer) { |
| + fActualColorBits = SkTMax(fColorBits, 24); |
| + |
| + GrBackendRenderTargetDesc desc; |
| + desc.fWidth = this->fWidth; |
| + desc.fHeight = this->fHeight; |
| + // TODO: Query the actual framebuffer for sRGB capable. However, to |
| + // preserve old (fake-linear) behavior, we don't do this. Instead, rely |
| + // on the flag (currently driven via 'C' mode in SampleApp). |
| + // |
| + // Also, we may not have real sRGB support (ANGLE, in particular), so check for |
| + // that, and fall back to L32: |
| + // |
| + // ... and, if we're using a 10-bit/channel FB0, it doesn't do sRGB conversion on write, |
| + // so pretend that it's non-sRGB 8888: |
| + if (fContext) { |
| + desc.fConfig = fContext->caps()->srgbSupport() && |
| + SkColorAndProfileAreGammaCorrect(fDisplayParams.fColorType, |
| + fDisplayParams.fProfileType) && |
| + (fColorBits != 30) ? kSkiaGamma8888_GrPixelConfig |
| + : kSkia8888_GrPixelConfig; |
| + desc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
| + desc.fSampleCnt = fSampleCount; |
| + desc.fStencilBits = fStencilBits; |
| + GrGLint buffer; |
| + GR_GL_CALL(fBackendContext, GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer)); |
| + desc.fRenderTargetHandle = buffer; |
| + fRenderTarget.reset(fContext->textureProvider()->wrapBackendRenderTarget(desc)); |
| + |
| + SkSurfaceProps props(fSurfaceProps); |
|
Brian Osman
2016/05/16 18:59:43
We should be setting the kGammaCorrect_Flag on the
jvanverth1
2016/05/17 15:37:18
Done.
|
| + if (// !IsGpuDeviceType(type) || |
| + kRGBA_F16_SkColorType == fDisplayParams.fColorType || fActualColorBits > 24) { |
| + // 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 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(desc.fWidth, desc.fHeight, |
| + fDisplayParams.fColorType, |
| + kUnknown_SkAlphaType, |
| + fDisplayParams.fProfileType); |
| + fBackbuffer = SkSurface::MakeRenderTarget(fContext, SkBudgeted::kNo, info, |
| + fDisplayParams.fMSAASampleCount, &props); |
| + } else { |
| + fBackbuffer = SkSurface::MakeRenderTargetDirect(fRenderTarget.get(), &props); |
| + } |
| + } |
| + } |
| + |
| + return fBackbuffer; |
| +} |
| + |
| +void GLWindowContext::swapBuffers() { |
| + if (//!IsGpuDeviceType(dType) || |
| + kRGBA_F16_SkColorType == fDisplayParams.fColorType || fActualColorBits > 24) { |
| + // We made/have an off-screen surface. Get the contents as an SkImage: |
| + SkImageInfo info = SkImageInfo::Make(fWidth, fHeight, |
| + fDisplayParams.fColorType, |
| + kUnknown_SkAlphaType, |
| + fDisplayParams.fProfileType); |
| + SkBitmap bm; |
| + bm.allocPixels(info); |
| + fBackbuffer->getCanvas()->readPixels(&bm, 0, 0); |
| + SkPixmap pm; |
| + bm.peekPixels(&pm); |
| + sk_sp<SkImage> image(SkImage::MakeTextureFromPixmap(fContext, pm, |
| + SkBudgeted::kNo)); |
| + GrTexture* texture = as_IB(image)->peekTexture(); |
| + SkASSERT(texture); |
| + |
| + // With ten-bit output, we need to manually apply the gamma of the output device |
| + // (unless we're in non-gamma correct mode, in which case our data is already |
| + // fake-sRGB, like we're expected to put in the 10-bit buffer): |
| + bool doGamma = (fActualColorBits == 30) && SkImageInfoIsGammaCorrect(info); |
| + fContext->applyGamma(fRenderTarget.get(), texture, doGamma ? 1.0f / 2.2f : 1.0f); |
| + } |
| + |
| + onSwapBuffers(); |
| +} |
| + |
| +void GLWindowContext::resize(uint32_t w, uint32_t h) { |
| + destroyContext(); |
| + |
| + initializeContext(nullptr, fDisplayParams); |
| +} |
| + |
| +void GLWindowContext::setDisplayParams(const DisplayParams& params) { |
| + destroyContext(); |
| + |
| + initializeContext(nullptr, params); |
| +} |
| + |
| +} //namespace sk_app |