Fix UI rendering on Skia/Win port w/GPU when screen scaling >= 200%

If screen scaling is not 1:1, we create a SkSurface using a off-screen
texture, everything is painted there and then a blit to the screen
framebuffer is done in SkiaWindow::paintImpl()
This commit is contained in:
David Capello 2015-10-05 17:40:55 -03:00
parent cc8b8cf52e
commit 9a8b7cd741
3 changed files with 62 additions and 13 deletions

View File

@ -40,9 +40,12 @@ public:
SkiaSurface(SkSurface* surface)
: m_surface(surface)
, m_canvas(m_surface->getCanvas())
, m_canvas(nullptr)
, m_clip(0, 0, width(), height())
{
ASSERT(m_surface);
if (m_surface)
m_canvas = m_surface->getCanvas();
}
~SkiaSurface() {

View File

@ -76,13 +76,35 @@ void SkiaWindow::paintImpl(HDC hdc)
surface->flush();
}
// If we are drawing inside an off-screen texture, here we have
// to blit that texture into the main framebuffer.
if (m_skSurfaceDirect != m_skSurface) {
GrBackendObject texID = m_skSurface->getTextureHandle(
SkSurface::kFlushRead_BackendHandleAccess);
GrBackendTextureDesc texDesc;
texDesc.fFlags = kNone_GrBackendTextureFlag;
texDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
texDesc.fWidth = m_lastSize.w / scale();
texDesc.fHeight = m_lastSize.h / scale();
texDesc.fConfig = kSkia8888_GrPixelConfig;
texDesc.fSampleCnt = m_sampleCount;
texDesc.fTextureHandle = texID;
SkAutoTUnref<SkImage> image(SkImage::NewFromTexture(m_grCtx, texDesc));
SkRect dstRect(SkRect::MakeWH(SkIntToScalar(m_lastSize.w),
SkIntToScalar(m_lastSize.h)));
SkPaint paint;
m_skSurfaceDirect->getCanvas()->drawImageRect(
image, dstRect, &paint,
SkCanvas::kStrict_SrcRectConstraint);
m_skSurfaceDirect->getCanvas()->flush();
}
// Flush GL context
m_grInterface->fFunctions.fFlush();
// We don't use double-buffer
//ASSERT(m_glCtx);
//if (m_glCtx)
// m_glCtx->swapBuffers();
break;
#endif // SK_SUPPORT_GPU
@ -157,6 +179,9 @@ bool SkiaWindow::attachANGLE()
void SkiaWindow::detachGL()
{
m_skSurfaceDirect.reset(nullptr);
m_skSurface.reset(nullptr);
m_grRenderTarget.reset(nullptr);
m_grCtx.reset(nullptr);
m_grInterface.reset(nullptr);
m_glCtx.reset(nullptr);
@ -164,20 +189,39 @@ void SkiaWindow::detachGL()
void SkiaWindow::createRenderTarget(const gfx::Size& size)
{
auto gl = &m_grInterface->fFunctions;
int scale = m_display->scale();
m_lastSize = size;
GrBackendRenderTargetDesc desc;
desc.fWidth = size.w / m_display->scale();
desc.fHeight = size.h / m_display->scale();
desc.fWidth = size.w;
desc.fHeight = size.h;
desc.fConfig = kSkia8888_GrPixelConfig;
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
desc.fSampleCnt = m_sampleCount;
desc.fStencilBits = m_stencilBits;
GrGLint buffer;
m_grInterface->fFunctions.fGetIntegerv(0x8CA6, &buffer); // GL_FRAMEBUFFER_BINDING = 0x8CA6
desc.fRenderTargetHandle = buffer;
desc.fRenderTargetHandle = 0; // direct frame buffer
m_grRenderTarget.reset(m_grCtx->textureProvider()->wrapBackendRenderTarget(desc));
m_skSurfaceDirect.reset(
SkSurface::NewRenderTargetDirect(m_grRenderTarget));
if (scale == 1) {
m_skSurface.reset(m_skSurfaceDirect);
}
else {
m_skSurface.reset(
SkSurface::NewRenderTarget(
m_grCtx,
SkSurface::kYes_Budgeted,
SkImageInfo::MakeN32Premul(MAX(1, size.w / scale),
MAX(1, size.h / scale)),
m_sampleCount));
}
if (!m_skSurface)
throw std::runtime_error("Error creating OpenGL surface for main display");
m_skSurface.reset(SkSurface::NewRenderTargetDirect(m_grRenderTarget));
m_display->setSkiaSurface(new SkiaSurface(m_skSurface));
}

View File

@ -52,9 +52,11 @@ private:
SkAutoTUnref<const GrGLInterface> m_grInterface;
SkAutoTUnref<GrContext> m_grCtx;
SkAutoTUnref<GrRenderTarget> m_grRenderTarget;
SkAutoTDelete<SkSurface> m_skSurfaceDirect;
SkAutoTDelete<SkSurface> m_skSurface;
int m_sampleCount;
int m_stencilBits;
gfx::Size m_lastSize;
#endif // SK_SUPPORT_GPU
DISABLE_COPYING(SkiaWindow);