aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/GrTextureStripAtlasTest.cpp
blob: 2def782f3822f94b647f1d7e6196aaf44a34b684 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"
#if SK_SUPPORT_GPU

#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrTextureStripAtlas.h"
#include "GrTypes.h"

// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    GrSurfaceDesc desc;
    desc.fWidth = 32;
    desc.fHeight = 32;
    desc.fConfig = kRGBA_8888_GrPixelConfig;

    sk_sp<GrSurfaceProxy> srcProxy;

    {
        SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
        memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);

        srcProxy = GrSurfaceProxy::MakeDeferred(*context->caps(), context->textureProvider(),
                                                desc, SkBudgeted::kYes,
                                                pixels.get(), 0);
    }

    // Add a pending read to the src texture, and then make it available for reuse.
    sk_sp<GrSurfaceProxy> targetProxy;
    GrSurface* srcSurface;

    {
        GrSurfaceDesc targetDesc = desc;
        targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;

        // We can't use GrSurfaceProxy::Copy bc we may be changing the dst proxy type
        sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
                                                                            targetDesc,
                                                                            SkBackingFit::kExact,
                                                                            SkBudgeted::kYes));
        REPORTER_ASSERT(reporter, dstContext);

        if (!dstContext->copy(srcProxy.get())) {
            return;
        }

        targetProxy = sk_ref_sp(dstContext->asDeferredSurface());

        srcSurface = srcProxy->instantiate(context->textureProvider());
        srcProxy.reset();
    }

    // Create an atlas with parameters that allow it to reuse the texture.
    GrTextureStripAtlas* atlas;

    {
        GrTextureStripAtlas::Desc atlasDesc;
        atlasDesc.fContext = context;
        atlasDesc.fConfig = desc.fConfig;
        atlasDesc.fWidth = desc.fWidth;
        atlasDesc.fHeight = desc.fHeight;
        atlasDesc.fRowHeight = 1;
        atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
    }

    // Write to the atlas' texture.
    int lockedRow;

    {
        SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
        size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
        SkBitmap bitmap;
        bitmap.allocPixels(info, rowBytes);
        memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
        lockedRow = atlas->lockRow(bitmap);
    }

    // The atlas' use of its texture shouldn't change which pixels got copied to the target.
    {
        SkAutoTMalloc<uint8_t> actualPixels(sizeof(uint32_t) * desc.fWidth * desc.fHeight);

        // TODO: move readPixels to GrSurfaceProxy?
        GrSurface* surf = targetProxy->instantiate(context->textureProvider());

        bool success = surf->readPixels(0, 0, desc.fWidth, desc.fHeight,
                                        kRGBA_8888_GrPixelConfig, actualPixels.get());
        REPORTER_ASSERT(reporter, success);

        bool good = true;

        const uint8_t* bytes = actualPixels.get();
        for (size_t i = 0; i < sizeof(uint32_t) * desc.fWidth * desc.fHeight; ++i, ++bytes) {
            if (0xFF != *bytes) {
                good = false;
                break;
            }
        }

        REPORTER_ASSERT(reporter, good);
    }

    if (!context->caps()->preferVRAMUseOverFlushes()) {
        // This is kindof dodgy since we released it!
        REPORTER_ASSERT(reporter, srcSurface == atlas->getTexture());
    }

    atlas->unlockRow(lockedRow);
}

#endif