Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTextureTile Class Reference

#include <kis_texture_tile.h>

Public Member Functions

int bindToActiveTexture (bool blockMipmapRegeneration)
 
QRectF imageRectInTexturePixels (const QRect &imageRect) const
 
 KisTextureTile (const QRect &imageRect, const KisGLTexturesInfo *texturesInfo, const QByteArray &fillData, KisOpenGL::FilterMode mode, KisOpenGLBufferCircularStorage *bufferStorage, int numMipmapLevels, QOpenGLFunctions *f)
 
void setBufferStorage (KisOpenGLBufferCircularStorage *bufferStorage)
 
void setNumMipmapLevels (int num)
 
QRect textureRectInImagePixels ()
 
QRect tileRectInImagePixels ()
 
QRectF tileRectInTexturePixels ()
 
void update (const KisTextureTileUpdateInfo &updateInfo, bool blockMipmapRegeneration)
 
 ~KisTextureTile ()
 

Private Member Functions

void regenerateMipmap ()
 
void restoreTextureParameters ()
 
void setNeedsMipmapRegeneration ()
 
void setPreparedLodPlane (int lod)
 
void setTextureParameters ()
 

Private Attributes

QOpenGLFunctions * f
 
KisOpenGLBufferCircularStoragem_bufferStorage
 
KisOpenGL::FilterMode m_filter
 
bool m_mipmapHasBeenAllocated = false
 
bool m_needsMipmapRegeneration
 
int m_numMipmapLevels
 
int m_preparedLodPlane
 
GLuint m_textureId
 
QRect m_textureRectInImagePixels
 
const KisGLTexturesInfom_texturesInfo
 
QRect m_tileRectInImagePixels
 
QRectF m_tileRectInTexturePixels
 

Detailed Description

Definition at line 40 of file kis_texture_tile.h.

Constructor & Destructor Documentation

◆ KisTextureTile()

KisTextureTile::KisTextureTile ( const QRect & imageRect,
const KisGLTexturesInfo * texturesInfo,
const QByteArray & fillData,
KisOpenGL::FilterMode mode,
KisOpenGLBufferCircularStorage * bufferStorage,
int numMipmapLevels,
QOpenGLFunctions * f )

Definition at line 72 of file kis_texture_tile.cpp.

76 : m_textureId(0)
77 , m_tileRectInImagePixels(imageRect)
78 , m_filter(filter)
79 , m_texturesInfo(texturesInfo)
82 , m_numMipmapLevels(numMipmapLevels)
83 , f(fcn)
84 , m_bufferStorage(bufferStorage)
85{
86 const GLvoid *fd = fillData.constData();
87
90
94
95 f->glGenTextures(1, &m_textureId);
96 f->glBindTexture(GL_TEXTURE_2D, m_textureId);
97
99
102
103 f->glTexImage2D(GL_TEXTURE_2D, 0,
108 m_texturesInfo->type, fd);
109
111
113}
QRect m_textureRectInImagePixels
const KisGLTexturesInfo * m_texturesInfo
QOpenGLFunctions * f
void restoreTextureParameters()
QRectF m_tileRectInTexturePixels
KisOpenGL::FilterMode m_filter
void setNeedsMipmapRegeneration()
QRect m_tileRectInImagePixels
KisOpenGLBufferCircularStorage * m_bufferStorage
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
void fillData(KisPaintDeviceSP pd, int w, int h, QDataStream &stream)
QRectF relativeRect(const QRect &br, const QRect &cr, const KisGLTexturesInfo *texturesInfo)

References KisGLTexturesInfo::border, f, fillData(), KisGLTexturesInfo::format, KisGLTexturesInfo::height, KisGLTexturesInfo::internalFormat, kisGrowRect(), m_bufferStorage, m_textureId, m_textureRectInImagePixels, m_texturesInfo, m_tileRectInImagePixels, m_tileRectInTexturePixels, relativeRect(), restoreTextureParameters(), setNeedsMipmapRegeneration(), setTextureParameters(), KisOpenGLBufferCircularStorage::size(), KisGLTexturesInfo::type, and KisGLTexturesInfo::width.

◆ ~KisTextureTile()

KisTextureTile::~KisTextureTile ( )

Definition at line 115 of file kis_texture_tile.cpp.

116{
117 f->glDeleteTextures(1, &m_textureId);
118}

References f, and m_textureId.

Member Function Documentation

◆ bindToActiveTexture()

int KisTextureTile::bindToActiveTexture ( bool blockMipmapRegeneration)

Binds the tile's texture to the current GL_TEXTURE_2D binding point, regenerates the mipmap if needed and returns the levelOfDetail that should be used for painting

Definition at line 120 of file kis_texture_tile.cpp.

121{
122 f->glBindTexture(GL_TEXTURE_2D, m_textureId);
123
124 if (m_needsMipmapRegeneration && !blockMipmapRegeneration) {
127 }
128
129 return m_preparedLodPlane;
130}
void setPreparedLodPlane(int lod)

References f, m_needsMipmapRegeneration, m_preparedLodPlane, m_textureId, regenerateMipmap(), and setPreparedLodPlane().

◆ imageRectInTexturePixels()

QRectF KisTextureTile::imageRectInTexturePixels ( const QRect & imageRect) const

Definition at line 384 of file kis_texture_tile.cpp.

385{
387 imageRect,
389
390}

References m_textureRectInImagePixels, m_texturesInfo, and relativeRect().

◆ regenerateMipmap()

void KisTextureTile::regenerateMipmap ( )
private

Definition at line 147 of file kis_texture_tile.cpp.

148{
149 f->glGenerateMipmap(GL_TEXTURE_2D);
152}

References f, m_mipmapHasBeenAllocated, and m_needsMipmapRegeneration.

◆ restoreTextureParameters()

void KisTextureTile::restoreTextureParameters ( )
inlineprivate

Definition at line 51 of file kis_texture_tile.cpp.

52{
53 // QPainter::drawText relies on this.
54 // Ref: https://bugreports.qt.io/browse/QTBUG-65496
55 f->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
56}

References f.

◆ setBufferStorage()

void KisTextureTile::setBufferStorage ( KisOpenGLBufferCircularStorage * bufferStorage)
inline

Definition at line 48 of file kis_texture_tile.h.

48 {
49 m_bufferStorage = bufferStorage;
50 }

References m_bufferStorage.

◆ setNeedsMipmapRegeneration()

void KisTextureTile::setNeedsMipmapRegeneration ( )
private

◆ setNumMipmapLevels()

void KisTextureTile::setNumMipmapLevels ( int num)
inline

Definition at line 52 of file kis_texture_tile.h.

52 {
54 }

References m_numMipmapLevels.

◆ setPreparedLodPlane()

void KisTextureTile::setPreparedLodPlane ( int lod)
private

Definition at line 141 of file kis_texture_tile.cpp.

142{
143 m_preparedLodPlane = lod;
145}

References m_needsMipmapRegeneration, and m_preparedLodPlane.

◆ setTextureParameters()

void KisTextureTile::setTextureParameters ( )
inlineprivate

Definition at line 26 of file kis_texture_tile.cpp.

27{
28
29 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
30 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
31 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
32 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, m_numMipmapLevels);
33 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
34 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_numMipmapLevels);
35
36 if ((m_texturesInfo->internalFormat == GL_RGBA8 && m_texturesInfo->format == GL_RGBA)
37#ifndef QT_OPENGL_ES_2
38 || (m_texturesInfo->internalFormat == GL_RGBA16 && m_texturesInfo->format == GL_RGBA)
39#endif
41 ) {
42 // If image format is RGBA8, swap the red and blue channels for the proper color
43 // This is for OpenGL ES support and only used if lacking GL_EXT_texture_format_BGRA8888
44 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
45 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
46 }
47
48 f->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
49}
#define GL_RGBA16_EXT
#define GL_CLAMP_TO_EDGE

References f, KisGLTexturesInfo::format, GL_CLAMP_TO_EDGE, GL_RGBA16_EXT, KisGLTexturesInfo::internalFormat, m_numMipmapLevels, and m_texturesInfo.

◆ textureRectInImagePixels()

QRect KisTextureTile::textureRectInImagePixels ( )
inline

Definition at line 62 of file kis_texture_tile.h.

62 {
64 }

References m_textureRectInImagePixels.

◆ tileRectInImagePixels()

QRect KisTextureTile::tileRectInImagePixels ( )
inline

Definition at line 58 of file kis_texture_tile.h.

58 {
60 }

References m_tileRectInImagePixels.

◆ tileRectInTexturePixels()

QRectF KisTextureTile::tileRectInTexturePixels ( )
inline

Definition at line 66 of file kis_texture_tile.h.

66 {
68 }

References m_tileRectInTexturePixels.

◆ update()

void KisTextureTile::update ( const KisTextureTileUpdateInfo & updateInfo,
bool blockMipmapRegeneration )

In some special case, when the Lod0 stroke is cancelled the following situation is possible:

1) The stroke is cancelled, Lod0 update is issued by the image. LodN level of the openGL times is still dirty.

2) [here, ideally, the canvas should be re-rendered, so that the mipmap would be regenerated in bindToActiveTexture() call, by in some cases (if you cancel and paint to quickly), that doesn't have time to happen]

3) The new LodN stroke issues a partial update of a LodN plane of the tile. But the plane is still dirty! We update a part of it, but we cannot regenerate the mipmap anymore, because the Lod0 level is not known yet!

To avoid this issue, we should regenerate the dirty mipmap before doing anything with the low-resolution plane.

Another case is when the user has Bilinear or Nearest Neighbour filtering selected and tries to use LoD functionality in animation. glTexSubImage2D() and textureLod() are defined only when all the planes were explicitly initialized with glTexImage2D(), which doesn't happen in case of bilinear- or nn-filtering. In this case !m_mipmapHasBeenAllocated condition comes in.

When in a mode that doesn't use mipmaps we should just switch back onto lod0 plane instead of requesting full mipmap regeneration.

Definition at line 154 of file kis_texture_tile.cpp.

155{
156 f->glBindTexture(GL_TEXTURE_2D, m_textureId);
157
159
160 const int patchLevelOfDetail = updateInfo.patchLevelOfDetail();
161 const QSize patchSize = updateInfo.realPatchSize();
162 const QPoint patchOffset = updateInfo.realPatchOffset();
163
192 if (!blockMipmapRegeneration &&
193 patchLevelOfDetail > 0 &&
195 !updateInfo.isEntireTileUpdated())
197
199 }
200
201 /*
202 * To avoid unsightly seams in wraparound mode, we extend the tile at the
203 * edges by just repeating the top/left/right/bottom row/column until the
204 * end of the texture. For that, we shuffle the data into a buffer, then
205 * pass that to the PBO. Previously, this code used to allocate up to four
206 * additional, single-pixel thick (and sometimes zero-pixel long) PBOs and
207 * hammer out the extensions through multiple calls to glTexSubImage2D, but
208 * that caused very long stalls on Android. If you are in the future and
209 * for some reason need to revert that, also update KisOpenGLImageTextures
210 * to properly account for these extra PBOs being used, since it assumes
211 * each tile only grabs one PBO from the circular buffer storage.
212 */
213 QSize tileSize = updateInfo.realTileSize();
214 int pixelSize = updateInfo.pixelSize();
215 int centerWidth = patchSize.width();
216 int centerHeight = patchSize.height();
217
218 int topHeight;
219 if (updateInfo.isTopmost()) {
220 topHeight = patchOffset.y();
221 } else {
222 topHeight = 0;
223 }
224
225 int leftWidth;
226 if (updateInfo.isLeftmost()) {
227 leftWidth = patchOffset.x();
228 } else {
229 leftWidth = 0;
230 }
231
232 int rightWidth;
233 if (updateInfo.isRightmost()) {
234 rightWidth = tileSize.width() - patchOffset.x() - centerWidth;
235 } else {
236 rightWidth = 0;
237 }
238
239 int bottomHeight;
240 if (updateInfo.isBottommost()) {
241 bottomHeight = tileSize.height() - patchOffset.y() - centerHeight;
242 } else {
243 bottomHeight = 0;
244 }
245
246 if (topHeight > 0 || leftWidth > 0 || rightWidth > 0 || bottomHeight > 0) {
247 int bufWidth = leftWidth + centerWidth + rightWidth;
248 int bufHeight = topHeight + centerHeight + bottomHeight;
249
250 int centerStride = centerWidth * pixelSize;
251 int leftStride = leftWidth * pixelSize;
252 int rightStride = rightWidth * pixelSize;
253 int bufStride = bufWidth * pixelSize;
254
255 QByteArray buf(bufStride * bufHeight, 0);
256 quint8 *bufData = reinterpret_cast<quint8 *>(buf.data());
257 const quint8 *patchData = updateInfo.data();
258
259 if (topHeight > 0) {
260 const quint8 *topSrcPtr = patchData;
261 quint8 *topDstPtr = bufData + leftStride;
262 for (int y = 0; y < topHeight; ++y) {
263 memcpy(topDstPtr, topSrcPtr, centerStride);
264 topDstPtr += bufStride;
265 }
266 }
267
268 if (leftWidth > 0) {
269 int leftDstSkip = centerStride + rightStride;
270 const quint8 *leftSrcPtr = patchData;
271 quint8 *leftDstPtr = bufData + (topHeight * bufStride);
272 for (int y = 0; y < centerHeight; ++y) {
273 for (int x = 0; x < leftWidth; ++x) {
274 memcpy(leftDstPtr, leftSrcPtr, pixelSize);
275 leftDstPtr += pixelSize;
276 }
277 leftSrcPtr += centerStride;
278 leftDstPtr += leftDstSkip;
279 }
280 }
281
282 {
283 const quint8 *centerSrcPtr = patchData;
284 quint8 *centerDstPtr = bufData + (topHeight * bufStride) + leftStride;
285 for (int y = 0; y < centerHeight; ++y) {
286 memcpy(centerDstPtr, centerSrcPtr, centerStride);
287 centerSrcPtr += centerStride;
288 centerDstPtr += bufStride;
289 }
290 }
291
292 if (rightWidth > 0) {
293 int rightDstSkip = leftStride + centerStride;
294 const quint8 *rightSrcPtr = patchData + (centerStride - pixelSize);
295 quint8 *rightDstPtr = bufData + (topHeight * bufStride) + rightDstSkip;
296 for (int y = 0; y < centerHeight; ++y) {
297 for (int x = 0; x < rightWidth; ++x) {
298 memcpy(rightDstPtr, rightSrcPtr, pixelSize);
299 rightDstPtr += pixelSize;
300 }
301 rightSrcPtr += centerStride;
302 rightDstPtr += rightDstSkip;
303 }
304 }
305
306 if (bottomHeight > 0) {
307 const quint8 *bottomSrcPtr = patchData + ((centerHeight - 1) * centerStride);
308 quint8 *bottomDstPtr = bufData + ((topHeight + centerHeight) * bufStride) + leftStride;
309 for (int y = 0; y < bottomHeight; ++y) {
310 memcpy(bottomDstPtr, bottomSrcPtr, centerStride);
311 bottomDstPtr += bufStride;
312 }
313 }
314
315 const GLvoid *fd = bufData;
317 f->glTexSubImage2D(GL_TEXTURE_2D,
318 patchLevelOfDetail,
319 patchOffset.x() - leftWidth,
320 patchOffset.y() - topHeight,
321 bufWidth,
322 bufHeight,
325 fd);
326
327 } else if (updateInfo.isEntireTileUpdated()) {
328 const GLvoid *fd = updateInfo.data();
330 m_bufferStorage, &fd, updateInfo.patchPixelsLength());
331
332 f->glTexImage2D(GL_TEXTURE_2D, patchLevelOfDetail,
334 patchSize.width(),
335 patchSize.height(), 0,
338 fd);
339
340 } else {
341 const GLvoid *fd = updateInfo.data();
342 const int size = centerWidth * centerHeight * pixelSize;
344 m_bufferStorage, &fd, size);
345
346 f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail,
347 patchOffset.x(), patchOffset.y(),
348 patchSize.width(), patchSize.height(),
351 fd);
352 }
353
356 // if (!updateInfo.isEntireTileUpdated() &&
357 // !(!patchLevelOfDetail || !m_preparedLodPlane || patchLevelOfDetail == m_preparedLodPlane)) {
358 // qDebug() << "WARNING: LodN switch is requested for the partial tile update!. Flickering is possible..." << ppVar(patchSize);
359 // qDebug() << " " << ppVar(m_preparedLodPlane);
360 // qDebug() << " " << ppVar(patchLevelOfDetail);
361 // }
362
364
365 if (!patchLevelOfDetail) {
376 } else {
378 }
379 } else {
380 setPreparedLodPlane(patchLevelOfDetail);
381 }
382}
@ NearestFilterMode
Definition kis_opengl.h:34
@ BilinearFilterMode
Definition kis_opengl.h:35
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisOpenGL::BilinearFilterMode, KisTextureTileUpdateInfo::data(), f, KisGLTexturesInfo::format, KisGLTexturesInfo::internalFormat, KisTextureTileUpdateInfo::isBottommost(), KisTextureTileUpdateInfo::isEntireTileUpdated(), KisTextureTileUpdateInfo::isLeftmost(), KisTextureTileUpdateInfo::isRightmost(), KisTextureTileUpdateInfo::isTopmost(), m_bufferStorage, m_filter, m_mipmapHasBeenAllocated, m_needsMipmapRegeneration, m_textureId, m_texturesInfo, KisOpenGL::NearestFilterMode, KisTextureTileUpdateInfo::patchLevelOfDetail(), KisTextureTileUpdateInfo::patchPixelsLength(), KisTextureTileUpdateInfo::pixelSize(), KisTextureTileUpdateInfo::realPatchOffset(), KisTextureTileUpdateInfo::realPatchSize(), KisTextureTileUpdateInfo::realTileSize(), regenerateMipmap(), restoreTextureParameters(), setNeedsMipmapRegeneration(), setPreparedLodPlane(), setTextureParameters(), and KisGLTexturesInfo::type.

Member Data Documentation

◆ f

QOpenGLFunctions* KisTextureTile::f
private

Definition at line 97 of file kis_texture_tile.h.

◆ m_bufferStorage

KisOpenGLBufferCircularStorage* KisTextureTile::m_bufferStorage
private

Definition at line 98 of file kis_texture_tile.h.

◆ m_filter

KisOpenGL::FilterMode KisTextureTile::m_filter
private

Definition at line 92 of file kis_texture_tile.h.

◆ m_mipmapHasBeenAllocated

bool KisTextureTile::m_mipmapHasBeenAllocated = false
private

Definition at line 99 of file kis_texture_tile.h.

◆ m_needsMipmapRegeneration

bool KisTextureTile::m_needsMipmapRegeneration
private

Definition at line 94 of file kis_texture_tile.h.

◆ m_numMipmapLevels

int KisTextureTile::m_numMipmapLevels
private

Definition at line 96 of file kis_texture_tile.h.

◆ m_preparedLodPlane

int KisTextureTile::m_preparedLodPlane
private

Definition at line 95 of file kis_texture_tile.h.

◆ m_textureId

GLuint KisTextureTile::m_textureId
private

Definition at line 87 of file kis_texture_tile.h.

◆ m_textureRectInImagePixels

QRect KisTextureTile::m_textureRectInImagePixels
private

Definition at line 91 of file kis_texture_tile.h.

◆ m_texturesInfo

const KisGLTexturesInfo* KisTextureTile::m_texturesInfo
private

Definition at line 93 of file kis_texture_tile.h.

◆ m_tileRectInImagePixels

QRect KisTextureTile::m_tileRectInImagePixels
private

Definition at line 89 of file kis_texture_tile.h.

◆ m_tileRectInTexturePixels

QRectF KisTextureTile::m_tileRectInTexturePixels
private

Definition at line 90 of file kis_texture_tile.h.


The documentation for this class was generated from the following files: