xref: /aosp_15_r20/external/skia/gm/skbug_8664.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkRect.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/core/SkScalar.h"
15 #include "tools/DecodeUtils.h"
16 #include "tools/Resources.h"
17 
18 DEF_SIMPLE_GM(skbug_8664, canvas, 830, 550) {
19     const struct {
20         SkScalar    fSx, fSy, fTx, fTy;
21     } xforms[] = {
22         { 1, 1, 0, 0 },
23         { 0.5f, 0.5f, 530, 0 },
24         { 0.25f, 0.25f, 530, 275 },
25         { 0.125f, 0.125f, 530, 420 },
26     };
27 
28     // Must be at least medium to require mipmaps when we downscale the image
29     SkSamplingOptions sampling(SkFilterMode::kLinear,
30                                SkMipmapMode::kLinear);
31 
32     sk_sp<SkImage> image(ToolUtils::GetResourceAsImage("images/mandrill_512.png"));
33 
34     SkPaint overlayPaint;
35     overlayPaint.setColor(0x80FFFFFF);
36 
37     // Make the overlay visible even when the downscaled images fail to render
38     canvas->clear(0xFF888888);
39 
40     canvas->translate(20, 20);
41     for (const auto& xform : xforms) {
42         canvas->save();
43         canvas->translate(xform.fTx, xform.fTy);
44         canvas->scale(xform.fSx, xform.fSy);
45 
46         // Draw an image, possibly down sampled, which forces us to generate mipmaps inline
47         // on the second iteration.
48         canvas->drawImage(image, 0, 0, sampling, nullptr);
49 
50         // Draw an overlay that requires the scissor test for its clipping, so that the mipmap
51         // generation + scissor interference bug is highlighted in Adreno 330 devices.
52         SkRect inner = SkRect::MakeLTRB(32.f, 32.f, 480.f, 480.f);
53         SkRect outer = inner.makeOutset(16.f, 16.f);
54 
55         // Clip to smaller rectangle
56         canvas->save();
57         canvas->clipRect(inner);
58         // Then apply a rotation and draw a larger rectangle to ensure the clip cannot be dropped
59         canvas->rotate(20.f);
60         canvas->drawRect(outer, overlayPaint);
61         canvas->restore();
62 
63         canvas->restore();
64     }
65 }
66