1 /*
2 * Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 #include "KisFrameCacheStoreTest.h"
19
20 #include <QTest>
21 #include <testutil.h>
22
23 #include <KoColor.h>
24 #include "KisAsyncAnimationRendererBase.h"
25 #include "kis_image_animation_interface.h"
26 #include "opengl/KisOpenGLUpdateInfoBuilder.h"
27
28 #include "KoColorSpaceRegistry.h"
29 #include "KoColorSpace.h"
30
31 // TODO: conversion options into a separate file!
32 #include "kis_update_info.h"
33
34 #include "opengl/kis_texture_tile_update_info.h"
35
36
37 #include "KisFrameCacheStore.h"
38
39 static const int maxTileSize = 256;
40
compareTextureTileUpdateInfo(KisTextureTileUpdateInfoSP tile1,KisTextureTileUpdateInfoSP tile2)41 bool compareTextureTileUpdateInfo(KisTextureTileUpdateInfoSP tile1, KisTextureTileUpdateInfoSP tile2)
42 {
43 KIS_COMPARE_RF(tile1->patchLevelOfDetail(), tile2->patchLevelOfDetail());
44 KIS_COMPARE_RF(tile1->realPatchOffset(), tile2->realPatchOffset());
45 KIS_COMPARE_RF(tile1->realPatchRect(), tile2->realPatchRect());
46 KIS_COMPARE_RF(tile1->realTileSize(), tile2->realTileSize());
47 KIS_COMPARE_RF(tile1->isTopmost(), tile2->isTopmost());
48 KIS_COMPARE_RF(tile1->isLeftmost(), tile2->isLeftmost());
49 KIS_COMPARE_RF(tile1->isRightmost(), tile2->isRightmost());
50 KIS_COMPARE_RF(tile1->isBottommost(), tile2->isBottommost());
51 KIS_COMPARE_RF(tile1->isEntireTileUpdated(), tile2->isEntireTileUpdated());
52
53 KIS_COMPARE_RF(tile1->tileCol(), tile2->tileCol());
54 KIS_COMPARE_RF(tile1->tileRow(), tile2->tileRow());
55 KIS_COMPARE_RF(tile1->pixelSize(), tile2->pixelSize());
56 KIS_COMPARE_RF(tile1->valid(), tile2->valid());
57
58 KIS_COMPARE_RF(tile1->patchPixelsLength(), tile2->patchPixelsLength());
59
60
61 const uint numRealPixelBytes = static_cast<uint>(tile1->realPatchRect().width() * tile1->realPatchRect().height() * tile1->pixelSize());
62
63 if (memcmp(tile1->data(), tile2->data(), numRealPixelBytes) != 0) {
64 qWarning() << "Tile pixels differ!";
65 qWarning() << " " << ppVar(tile1->tileCol()) << ppVar(tile1->tileRow());
66 qWarning() << " " << ppVar(numRealPixelBytes);
67
68 quint8 *src = tile1->data();
69 quint8 *dst = tile2->data();
70
71 for (uint i = 0; i < numRealPixelBytes; i++) {
72 if (*src != *dst) {
73 qDebug() << " " << ppVar(i) << ppVar(*src) << ppVar(*dst);
74 }
75
76 src++;
77 dst++;
78 }
79
80 return false;
81 }
82
83 return true;
84 }
85
86
compareUpdateInfo(KisOpenGLUpdateInfoSP info1,KisOpenGLUpdateInfoSP info2)87 bool compareUpdateInfo(KisOpenGLUpdateInfoSP info1, KisOpenGLUpdateInfoSP info2)
88 {
89 KIS_COMPARE_RF(info1->dirtyImageRect(), info2->dirtyImageRect());
90 KIS_COMPARE_RF(info1->levelOfDetail(), info2->levelOfDetail());
91 KIS_COMPARE_RF(info1->tileList.size(), info2->tileList.size());
92
93 for (int i = 0; i < info1->tileList.size(); i++) {
94 if (!compareTextureTileUpdateInfo(info1->tileList[i], info2->tileList[i])) {
95 return false;
96 }
97 }
98
99 return true;
100 }
101
102
103 class TestFramesRenderer : public KisAsyncAnimationRendererBase
104 {
105 Q_OBJECT
106
107 public:
TestFramesRenderer()108 TestFramesRenderer()
109 : m_pool(m_poolRegistry.getPool(maxTileSize, maxTileSize))
110 {
111 m_updateInfoBuilder.setTextureInfoPool(m_pool);
112
113 const KoColorSpace *dstColorSpace = KoColorSpaceRegistry::instance()->rgb8();
114 m_updateInfoBuilder.setConversionOptions(
115 ConversionOptions(dstColorSpace,
116 KoColorConversionTransformation::internalRenderingIntent(),
117 KoColorConversionTransformation::internalConversionFlags()));
118
119 // TODO: refactor setting texture size in raw values!
120 m_updateInfoBuilder.setTextureBorder(8);
121 m_updateInfoBuilder.setEffectiveTextureSize(QSize(256 - 16, 256 - 16));
122
123 connect(this, SIGNAL(sigCompleteRegenerationInternal(int)), SLOT(notifyFrameCompleted(int)));
124 connect(this, SIGNAL(sigCancelRegenerationInternal(int)), SLOT(notifyFrameCancelled(int)));
125 }
126
frameCompletedCallback(int frame,const KisRegion & requestedRegion)127 void frameCompletedCallback(int frame, const KisRegion &requestedRegion) override {
128 KisImageSP image = requestedImage();
129 KIS_SAFE_ASSERT_RECOVER_NOOP(frame == image->animationInterface()->currentTime());
130
131 // by default we request update for the entire image
132 KIS_SAFE_ASSERT_RECOVER_NOOP(requestedRegion == image->bounds());
133
134 KisOpenGLUpdateInfoSP info = m_updateInfoBuilder.buildUpdateInfo(image->bounds(), image, true);
135
136 KIS_ASSERT_RECOVER_NOOP(info);
137 qDebug() << ppVar(info->tileList.size());
138
139 KisOpenGLUpdateInfoSP infoForSave = m_updateInfoBuilder.buildUpdateInfo(image->bounds(), image, true);
140 m_store.saveFrame(11, infoForSave, image->bounds());
141
142 KIS_SAFE_ASSERT_RECOVER_NOOP(m_store.hasFrame(11));
143
144 KisOpenGLUpdateInfoSP loadedInfo = m_store.loadFrame(11, m_updateInfoBuilder);
145
146 qDebug() << ppVar(loadedInfo->tileList.size());
147
148 KIS_SAFE_ASSERT_RECOVER_NOOP(compareUpdateInfo(info, loadedInfo));
149
150
151 emit sigCompleteRegenerationInternal(frame);
152 }
153
frameCancelledCallback(int frame)154 void frameCancelledCallback(int frame) override {
155 emit sigCancelRegenerationInternal(frame);
156 }
157
158 Q_SIGNALS:
159 void sigCompleteRegenerationInternal(int frame);
160 void sigCancelRegenerationInternal(int frame);
161
162 private:
163 KisOpenGLUpdateInfoBuilder m_updateInfoBuilder;
164 KisTextureTileInfoPoolRegistry m_poolRegistry;
165 KisTextureTileInfoPoolSP m_pool;
166 KisFrameCacheStore m_store;
167 };
168
169
170
171
test()172 void KisFrameCacheStoreTest::test()
173 {
174 QRect refRect(QRect(0,0,512,512));
175 TestUtil::MaskParent p(refRect);
176 const KoColor fillColor(Qt::red, p.image->colorSpace());
177
178 KisPaintLayerSP layer1 = p.layer;
179 layer1->paintDevice()->fill(QRect(100,100,300,300), fillColor);
180
181 TestFramesRenderer renderer;
182 renderer.startFrameRegeneration(p.image, 10);
183
184
185 p.image->waitForDone();
186
187 while (renderer.isActive()) {
188 QTest::qWait(500);
189 }
190
191 }
192
193 QTEST_MAIN(KisFrameCacheStoreTest)
194
195 #include "KisFrameCacheStoreTest.moc"
196