• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 "SkTypes.h"
9 
10 #include "SkCanvas.h"
11 #include "SkSurface.h"
12 
13 #if SK_SUPPORT_GPU
14 
15 #include "GrContext.h"
16 #include "GrTest.h"
17 #include "Test.h"
18 
read_pixels(sk_sp<SkSurface> surface)19 static SkBitmap read_pixels(sk_sp<SkSurface> surface) {
20     SkBitmap bmp;
21     bmp.allocN32Pixels(surface->width(), surface->height());
22     if (!surface->getCanvas()->readPixels(bmp, 0, 0)) {
23         SkDebugf("readPixels failed\n");
24     }
25     return bmp;
26 }
27 
make_surface(GrContext * context)28 static sk_sp<SkSurface> make_surface(GrContext* context) {
29     SkImageInfo info = SkImageInfo::Make(50, 50, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
30     return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 4,
31                                        kBottomLeft_GrSurfaceOrigin, nullptr);
32 }
33 
34 // Tests that readPixels returns up-to-date results. Demonstrates a bug on Galaxy S6
35 // (Mali T760), in MSAA mode.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(skbug6653,reporter,ctxInfo)36 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(skbug6653, reporter, ctxInfo) {
37     GrContext* ctx = ctxInfo.grContext();
38     SkRect rect = SkRect::MakeWH(50, 50);
39 
40     SkPaint paint;
41     paint.setColor(SK_ColorWHITE);
42     paint.setStrokeWidth(5);
43     paint.setStyle(SkPaint::kStroke_Style);
44 
45     // The one device that fails this test (Galaxy S6) does so in a flaky fashion. Trying many
46     // times makes it more likely to fail. Also, interacting with the phone (eg swiping between
47     // different home screens) while the test is running makes it fail close to 100%.
48     static const int kNumIterations = 50;
49 
50     for (int i = 0; i < kNumIterations; ++i) {
51         auto s0 = make_surface(ctx);
52         if (!s0) {
53             // MSAA may not be supported
54             return;
55         }
56 
57         auto s1 = make_surface(ctx);
58         s1->getCanvas()->clear(SK_ColorBLACK);
59         s1->getCanvas()->drawOval(rect, paint);
60         SkBitmap b1 = read_pixels(s1);
61         s1 = nullptr;
62 
63         // The bug requires that all three of the following surfaces are cleared to the same color
64         auto s2 = make_surface(ctx);
65         s2->getCanvas()->clear(SK_ColorBLUE);
66         SkBitmap b2 = read_pixels(s2);
67         s2 = nullptr;
68 
69         auto s3 = make_surface(ctx);
70         s3->getCanvas()->clear(SK_ColorBLUE);
71         SkBitmap b3 = read_pixels(s3);
72         s0->getCanvas()->drawBitmap(b3, 0, 0);
73         s3 = nullptr;
74 
75         auto s4 = make_surface(ctx);
76         s4->getCanvas()->clear(SK_ColorBLUE);
77         s4->getCanvas()->drawOval(rect, paint);
78 
79         // When this fails, b4 will "succeed", but return an empty bitmap (containing just the
80         // clear color). Regardless, b5 will contain the oval that was just drawn, so diffing the
81         // two bitmaps tests for the failure case.
82         SkBitmap b4 = read_pixels(s4);
83         SkBitmap b5 = read_pixels(s4);
84 
85         bool match = true;
86         for (int y = 0; y < b4.height() && match; ++y) {
87             for (int x = 0; x < b4.width() && match; ++x) {
88                 uint32_t pixelA = *b4.getAddr32(x, y);
89                 uint32_t pixelB = *b5.getAddr32(x, y);
90                 if (pixelA != pixelB) {
91                     match = false;
92                 }
93             }
94         }
95 
96         REPORTER_ASSERT(reporter, match);
97     }
98 }
99 
100 #endif
101