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