RecordReplaceDrawTest.cpp revision c88cedaf8806cc9afa36497dc93eb0d1c329fb6c
1d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips/*
2d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * Copyright 2014 Google Inc.
3d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips *
4d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * Use of this source code is governed by a BSD-style license that can be
5d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * found in the LICENSE file.
6d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips */
7d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
8d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#if SK_SUPPORT_GPU
9d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
10d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "Test.h"
11d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
12e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips#include "GrContextFactory.h"
13e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips#include "GrLayerCache.h"
14ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "GrRecordReplaceDraw.h"
15ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "RecordTestUtils.h"
16d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkBBHFactory.h"
17ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "SkPictureRecorder.h"
18d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecordDraw.h"
19d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecorder.h"
20d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkUtils.h"
21d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
22d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kWidth = 100;
23d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kHeight = 100;
24d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
25d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsclass JustOneDraw : public SkDrawPictureCallback {
26d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipspublic:
27d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw() : fCalls(0) {}
28d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
29d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
30d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsprivate:
31d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    int fCalls;
32d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips};
33d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
34d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure the abort callback works
35d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Abort, r) {
36ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
37ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
38ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
39ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        // Record two commands.
40ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
41ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
42ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
43ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
44ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
45ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
46ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
47ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
48d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
49d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
50d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
51d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
52d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw callback;
53e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), &callback);
54d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
55d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 3 == rerecord.count());
56d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
57d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
58d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
59d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
60d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
61d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure GrRecordReplaceDraw balances unbalanced saves
62d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Unbalanced, r) {
63ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
64ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
65ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
66ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
67ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
68ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
69ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        // We won't balance this, but GrRecordReplaceDraw will for us.
70ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->save();
71ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
72ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
73ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
74d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
75d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
76d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
77d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
78e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), NULL/*callback*/);
79d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
80d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 4 == rerecord.count());
81d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
82d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
83d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
84d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 3);
85d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
86d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
87d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Test out the layer replacement functionality with and w/o a BBH
88e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillipsvoid test_replacements(skiatest::Reporter* r, GrContext* context, bool useBBH) {
89ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
90ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
91ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
92ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkRTreeFactory bbhFactory;
93ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
944477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight),
95ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips                                                   useBBH ? &bbhFactory : NULL);
96ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
97c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein        SkPaint paint;
98c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein        canvas->saveLayer(NULL, &paint);
99ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->clear(SK_ColorRED);
100ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->restore();
101ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)),
102ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips                         SkPaint());
103ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
104ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
105d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
106e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    unsigned key[1] = { 0 };
10701d6e5f462d1d52203ee1a6660415877e4cf2dderobertphillips
108c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein    SkPaint paint;
109e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrLayerCache* layerCache = context->getLayerCache();
110c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein    GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2,
111e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips                                                         SkIRect::MakeWH(kWidth, kHeight),
112c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein                                                         SkMatrix::I(), key, 1, &paint);
113e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips
114e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrSurfaceDesc desc;
115e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    desc.fConfig = kSkia8888_GrPixelConfig;
116e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    desc.fFlags = kRenderTarget_GrSurfaceFlag;
117e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    desc.fWidth = kWidth;
118e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    desc.fHeight = kHeight;
119e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    desc.fSampleCnt = 0;
120e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips
121e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
122e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight));
123d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
124d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoTUnref<SkBBoxHierarchy> bbh;
125d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
126d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
127d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
128e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), NULL/*callback*/);
129d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
13046625e06e23b65c05013fc686a8223d6d5b49050robertphillips    REPORTER_ASSERT(r, 7 == rerecord.count());
131d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
13246625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
13346625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
134e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
13546625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 4);
13646625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 5);
13746625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 6);
138d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
139d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
140e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillipsDEF_GPUTEST(RecordReplaceDraw, r, factory) {
141e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
142e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
143e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        if (!GrContextFactory::IsRenderingGLContext(glType)) {
144e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips            continue;
145e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        }
146e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        GrContext* context = factory->get(glType);
147e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        if (NULL == context) {
148e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips            continue;
149e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        }
150e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips
151e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        test_replacements(r, context, true);
152e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips        test_replacements(r, context, false);
153e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    }
154e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips}
155d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
156d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#endif
157