From 4edd42029081d057f3ab25d56449a8b326586c87 Mon Sep 17 00:00:00 2001 From: Michael Ludwig Date: Tue, 15 Jan 2019 12:09:25 -0500 Subject: [PATCH] Bugfix for Nexus 5 mipmap+scissor generation failure Bug: skia:8664 Change-Id: Ic1b4f5afb2847eabb2290cbba808c5692a876972 Reviewed-on: https://skia-review.googlesource.com/c/182152 Auto-Submit: Michael Ludwig Reviewed-by: Robert Phillips Commit-Queue: Robert Phillips --- gm/skbug_8664.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++ gn/gm.gni | 1 + 2 files changed, 59 insertions(+) create mode 100644 gm/skbug_8664.cpp diff --git a/gm/skbug_8664.cpp b/gm/skbug_8664.cpp new file mode 100644 index 0000000000..4feba4b54e --- /dev/null +++ b/gm/skbug_8664.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2019 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" + +#include "Resources.h" + +DEF_SIMPLE_GM(skbug_8664, canvas, 830, 550) { + const struct { + SkScalar fSx, fSy, fTx, fTy; + } xforms[] = { + { 1, 1, 0, 0 }, + { 0.5f, 0.5f, 530, 0 }, + { 0.25f, 0.25f, 530, 275 }, + { 0.125f, 0.125f, 530, 420 }, + }; + + SkPaint imagePaint; + // Must be at least medium to require mipmaps when we downscale the image + imagePaint.setFilterQuality(kMedium_SkFilterQuality); + sk_sp image(GetResourceAsImage("images/mandrill_512.png")); + + SkPaint overlayPaint; + overlayPaint.setColor(0x80FFFFFF); + + // Make the overlay visible even when the downscaled images fail to render + canvas->clear(0xFF888888); + + canvas->translate(20, 20); + for (const auto& xform : xforms) { + canvas->save(); + canvas->translate(xform.fTx, xform.fTy); + canvas->scale(xform.fSx, xform.fSy); + + // Draw an image, possibly down sampled, which forces us to generate mipmaps inline + // on the second iteration. + canvas->drawImage(image, 0, 0, &imagePaint); + + // Draw an overlay that requires the scissor test for its clipping, so that the mipmap + // generation + scissor interference bug is highlighted in Adreno 330 devices. + SkRect inner = SkRect::MakeLTRB(32.f, 32.f, 480.f, 480.f); + SkRect outer = inner.makeOutset(16.f, 16.f); + + // Clip to smaller rectangle + canvas->save(); + canvas->clipRect(inner); + // Then apply a rotation and draw a larger rectangle to ensure the clip cannot be dropped + canvas->rotate(20.f); + canvas->drawRect(outer, overlayPaint); + canvas->restore(); + + canvas->restore(); + } +} diff --git a/gn/gm.gni b/gn/gm.gni index 9a2313d86d..8cef2abe47 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -299,6 +299,7 @@ gm_sources = [ "$_gm/skbug_257.cpp", "$_gm/skbug_4868.cpp", "$_gm/skbug_5321.cpp", + "$_gm/skbug_8664.cpp", "$_gm/skbug1719.cpp", "$_gm/skinning.cpp", "$_gm/smallarc.cpp",