Example #1
0
KisTextureTile::~KisTextureTile()
{
#ifdef USE_PIXEL_BUFFERS
    KisConfig cfg;
    if (cfg.useOpenGLTextureBuffer()) {
        delete m_glBuffer;
    }
#endif
    glDeleteTextures(1, &m_textureId);
}
Example #2
0
void KisOpenGLCanvas2::slotConfigChanged()
{
    KisConfig cfg;
    d->checkSizeScale = KisOpenGLImageTextures::BACKGROUND_TEXTURE_CHECK_SIZE / static_cast<GLfloat>(cfg.checkSize());
    d->scrollCheckers = cfg.scrollCheckers();

    d->openGLImageTextures->generateCheckerTexture(createCheckersImage(cfg.checkSize()));
    d->openGLImageTextures->updateConfig(cfg.useOpenGLTextureBuffer(), cfg.numMipmapLevels());
    d->filterMode = (KisOpenGL::FilterMode) cfg.openGLFilteringMode();

    notifyConfigChanged();
}
Example #3
0
KisTextureTile::KisTextureTile(QRect imageRect, const KisGLTexturesInfo *texturesInfo,
                               const QByteArray &fillData, FilterMode filter)

    : m_textureId(0)
#ifdef USE_PIXEL_BUFFERS
    , m_glBuffer(0)
#endif
    , m_tileRectInImagePixels(imageRect)
    , m_filter(filter)
    , m_texturesInfo(texturesInfo)
    , m_needsMipmapRegeneration(false)
{
    const GLvoid *fd = fillData.constData();

    m_textureRectInImagePixels =
        stretchRect(m_tileRectInImagePixels, texturesInfo->border);

    m_tileRectInTexturePixels = relativeRect(m_textureRectInImagePixels,
                                m_tileRectInImagePixels,
                                m_texturesInfo);

    glGenTextures(1, &m_textureId);
    glBindTexture(GL_TEXTURE_2D, m_textureId);

    setTextureParameters();

#ifdef USE_PIXEL_BUFFERS
    createTextureBuffer(fillData);
    // we set fill data to 0 so the next glTexImage2D call uses our buffer
    fd = 0;
#endif

    glTexImage2D(GL_TEXTURE_2D, 0,
                 m_texturesInfo->internalFormat,
                 m_texturesInfo->width,
                 m_texturesInfo->height, 0,
                 m_texturesInfo->format,
                 m_texturesInfo->type, fd);

#ifdef USE_PIXEL_BUFFERS
    KisConfig cfg;
    if (cfg.useOpenGLTextureBuffer()) {
        m_glBuffer->release();
    }
#endif

    setNeedsMipmapRegeneration();
}
Example #4
0
void KisTextureTile::createTextureBuffer(const QByteArray &fillData)
{
    KisConfig cfg;
    if (cfg.useOpenGLTextureBuffer()) {
        m_glBuffer = new QGLBuffer(QGLBuffer::PixelUnpackBuffer);
        m_glBuffer->setUsagePattern(QGLBuffer::DynamicDraw);
        m_glBuffer->create();

        m_glBuffer->bind();

        m_glBuffer->allocate(fillData.size());

        void *vid = m_glBuffer->map(QGLBuffer::WriteOnly);
        memcpy(vid, fillData.constData(), fillData.size());
        m_glBuffer->unmap();

    }
    else {
        m_glBuffer = 0;
    }
}
Example #5
0
void KisTextureTile::update(const KisTextureTileUpdateInfo &updateInfo)
{
    glBindTexture(GL_TEXTURE_2D, m_textureId);

    setTextureParameters();

    const GLvoid *fd = updateInfo.data();
#ifdef USE_PIXEL_BUFFERS
    KisConfig cfg;
    if (!m_glBuffer) {
        QByteArray ba;
        ba.fromRawData((const char*)updateInfo.data(), updateInfo.patchPixelsLength());
        createTextureBuffer(ba);
    }
#endif

    if (updateInfo.isEntireTileUpdated()) {

#ifdef USE_PIXEL_BUFFERS

        if (cfg.useOpenGLTextureBuffer()) {

            m_glBuffer->bind();
            m_glBuffer->allocate(updateInfo.patchPixelsLength());

            void *vid = m_glBuffer->map(QGLBuffer::WriteOnly);
            memcpy(vid, fd, updateInfo.patchPixelsLength());
            m_glBuffer->unmap();

            // we set fill data to 0 so the next glTexImage2D call uses our buffer
            fd = 0;
        }
#endif

        glTexImage2D(GL_TEXTURE_2D, 0,
                     m_texturesInfo->internalFormat,
                     m_texturesInfo->width,
                     m_texturesInfo->height, 0,
                     m_texturesInfo->format,
                     m_texturesInfo->type,
                     fd);

#ifdef USE_PIXEL_BUFFERS
        if (cfg.useOpenGLTextureBuffer()) {
            m_glBuffer->release();
        }
#endif

    }
    else {
        QPoint patchOffset = updateInfo.patchOffset();
        QSize patchSize = updateInfo.patchSize();

#ifdef USE_PIXEL_BUFFERS
        if (cfg.useOpenGLTextureBuffer()) {
            m_glBuffer->bind();
            quint32 size = patchSize.width() * patchSize.height() * updateInfo.pixelSize();
            m_glBuffer->allocate(size);

            void *vid = m_glBuffer->map(QGLBuffer::WriteOnly);
            memcpy(vid, fd, size);
            m_glBuffer->unmap();

            // we set fill data to 0 so the next glTexImage2D call uses our buffer
            fd = 0;
        }
#endif

        glTexSubImage2D(GL_TEXTURE_2D, 0,
                        patchOffset.x(), patchOffset.y(),
                        patchSize.width(), patchSize.height(),
                        m_texturesInfo->format,
                        m_texturesInfo->type,
                        fd);

#ifdef USE_PIXEL_BUFFERS
        if (cfg.useOpenGLTextureBuffer()) {
            m_glBuffer->release();
        }
#endif

    }

    /**
     * On the boundaries of KisImage, there is a border-effect as well.
     * So we just repeat the bounding pixels of the image to make
     * bilinear interpolator happy.
     */

    /**
     * WARN: The width of the stripes will be equal to the broder
     *       width of the tiles.
     */

    const int pixelSize = updateInfo.pixelSize();
    const QRect imageRect = updateInfo.imageRect();
    const QPoint patchOffset = updateInfo.patchOffset();
    const QSize patchSize = updateInfo.patchSize();
    const QRect patchRect = QRect(m_textureRectInImagePixels.topLeft() +
                                  patchOffset,
                                  patchSize);
    const QSize tileSize = updateInfo.tileRect().size();


    if(imageRect.top() == patchRect.top()) {
        int start = 0;
        int end = patchOffset.y() - 1;
        for (int i = start; i <= end; i++) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                            patchOffset.x(), i,
                            patchSize.width(), 1,
                            m_texturesInfo->format,
                            m_texturesInfo->type,
                            updateInfo.data());
        }
    }

    if (imageRect.bottom() == patchRect.bottom()) {
        int shift = patchSize.width() * (patchSize.height() - 1) *
                    pixelSize;

        int start = patchOffset.y() + patchSize.height();
        int end = tileSize.height() - 1;
        for (int i = start; i < end; i++) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                            patchOffset.x(), i,
                            patchSize.width(), 1,
                            m_texturesInfo->format,
                            m_texturesInfo->type,
                            updateInfo.data() + shift);
        }
    }

    if (imageRect.left() == patchRect.left()) {

        QByteArray columnBuffer(patchSize.height() * pixelSize, 0);

        quint8 *srcPtr = updateInfo.data();
        quint8 *dstPtr = (quint8*) columnBuffer.data();
        for(int i = 0; i < patchSize.height(); i++) {
            memcpy(dstPtr, srcPtr, pixelSize);

            srcPtr += patchSize.width() * pixelSize;
            dstPtr += pixelSize;
        }

        int start = 0;
        int end = patchOffset.x() - 1;
        for (int i = start; i <= end; i++) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                            i, patchOffset.y(),
                            1, patchSize.height(),
                            m_texturesInfo->format,
                            m_texturesInfo->type,
                            columnBuffer.constData());
        }
    }

    if (imageRect.right() == patchRect.right()) {

        QByteArray columnBuffer(patchSize.height() * pixelSize, 0);

        quint8 *srcPtr = updateInfo.data() + (patchSize.width() - 1) * pixelSize;
        quint8 *dstPtr = (quint8*) columnBuffer.data();
        for(int i = 0; i < patchSize.height(); i++) {
            memcpy(dstPtr, srcPtr, pixelSize);

            srcPtr += patchSize.width() * pixelSize;
            dstPtr += pixelSize;
        }

        int start = patchOffset.x() + patchSize.width();
        int end = tileSize.width() - 1;
        for (int i = start; i <= end; i++) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                            i, patchOffset.y(),
                            1, patchSize.height(),
                            m_texturesInfo->format,
                            m_texturesInfo->type,
                            columnBuffer.constData());
        }
    }

    setNeedsMipmapRegeneration();
}