Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef70a20a authored by Jason Sams's avatar Jason Sams
Browse files

Implement sub updates for mipmap levels and cubmaps.

Change-Id: I7c41263a0c1e583574d0c1fcb64b1a0440b5b555
parent 9333e64f
Loading
Loading
Loading
Loading
+33 −58
Original line number Diff line number Diff line
@@ -188,12 +188,7 @@ void Allocation::uploadToTexture(const Context *rsc) {
        isFirstUpload = true;
    }

    GLenum target = (GLenum)getGLTarget();
    if (target == GL_TEXTURE_2D) {
        upload2DTexture(isFirstUpload, mPtr);
    } else if (target == GL_TEXTURE_CUBE_MAP) {
        uploadCubeTexture(isFirstUpload);
    }
    upload2DTexture(isFirstUpload);

    if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
        freeScriptMemory();
@@ -202,6 +197,15 @@ void Allocation::uploadToTexture(const Context *rsc) {
    rsc->checkError("Allocation::uploadToTexture");
}

const static GLenum gFaceOrder[] = {
    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
                                 uint32_t lod, RsAllocationCubemapFace face,
                                 uint32_t w, uint32_t h) {
@@ -210,10 +214,14 @@ void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
    GLenum target = (GLenum)getGLTarget();
    glBindTexture(target, mTextureID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexSubImage2D(GL_TEXTURE_2D, lod, xoff, yoff, w, h, format, type, ptr);
    GLenum t = GL_TEXTURE_2D;
    if (mType->getDimFaces()) {
        t = gFaceOrder[face];
    }
    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
}

void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
void Allocation::upload2DTexture(bool isFirstUpload) {
    GLenum type = mType->getElement()->getComponent().getGLType();
    GLenum format = mType->getElement()->getComponent().getGLFormat();

@@ -221,64 +229,31 @@ void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
    glBindTexture(target, mTextureID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    uint32_t faceCount = 1;
    if (mType->getDimFaces()) {
        faceCount = 6;
    }

    for (uint32_t face = 0; face < faceCount; face ++) {
        for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
        const uint8_t *p = (const uint8_t *)ptr;
        p += mType->getLODOffset(lod);
            const uint8_t *p = (const uint8_t *)mPtr;
            p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);

            GLenum t = GL_TEXTURE_2D;
            if (mType->getDimFaces()) {
                t = gFaceOrder[face];
            }

            if (isFirstUpload) {
            glTexImage2D(GL_TEXTURE_2D, lod, format,
                glTexImage2D(t, lod, format,
                             mType->getLODDimX(lod), mType->getLODDimY(lod),
                             0, format, type, p);
            } else {
            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
                glTexSubImage2D(t, lod, 0, 0,
                                mType->getLODDimX(lod), mType->getLODDimY(lod),
                                format, type, p);
            }
        }

    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
#ifndef ANDROID_RS_BUILD_FOR_HOST
        glGenerateMipmap(target);
#endif //ANDROID_RS_BUILD_FOR_HOST
    }
}

void Allocation::uploadCubeTexture(bool isFirstUpload) {
    GLenum type = mType->getElement()->getComponent().getGLType();
    GLenum format = mType->getElement()->getComponent().getGLFormat();

    GLenum target = (GLenum)getGLTarget();
    glBindTexture(target, mTextureID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    GLenum faceOrder[] = {
        GL_TEXTURE_CUBE_MAP_POSITIVE_X,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
        GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
        GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
    };

    Adapter2D adapt(getContext(), this);
    for (uint32_t face = 0; face < 6; face ++) {
        adapt.setFace(face);

        for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
            adapt.setLOD(lod);

            uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));

            if (isFirstUpload) {
                glTexImage2D(faceOrder[face], lod, format,
                             adapt.getDimX(), adapt.getDimY(),
                             0, format, type, ptr);
            } else {
                glTexSubImage2D(faceOrder[face], lod, 0, 0,
                                adapt.getDimX(), adapt.getDimY(),
                                format, type, ptr);
            }
        }
    }

    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
@@ -364,7 +339,7 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod,
    if (mPtr) {
        const uint8_t *src = static_cast<const uint8_t *>(data);
        uint8_t *dst = static_cast<uint8_t *>(mPtr);
        dst += mType->getLODOffset(lod, xoff, yoff);
        dst += mType->getLODFaceOffset(lod, face, xoff, yoff);

        //LOGE("            %p  %p  %i  ", dst, src, eSize);
        for (uint32_t line=yoff; line < (yoff+h); line++) {
+3 −4
Original line number Diff line number Diff line
@@ -105,9 +105,6 @@ public:
        return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE;
    }

    void upload2DTexture(bool isFirstUpload, const void *ptr);
    void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
                         uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h);

protected:
    ObjectBaseRef<const Type> mType;
@@ -149,7 +146,9 @@ protected:

private:
    void init(Context *rsc, const Type *);
    void uploadCubeTexture(bool isFirstUpload);
    void upload2DTexture(bool isFirstUpload);
    void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
                         uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h);

    void allocScriptMemory();
    void freeScriptMemory();
+11 −0
Original line number Diff line number Diff line
@@ -132,6 +132,17 @@ uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) co
    return offset;
}

uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const {
    uint32_t offset = mLODs[lod].mOffset;
    offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();

    if (face != 0) {
        uint32_t faceOffset = getSizeBytes() / 6;
        offset += faceOffset * face;
    }
    return offset;
}

void Type::dumpLOGV(const char *prefix) const {
    char buf[1024];
    ObjectBase::dumpLOGV(prefix);
+3 −1
Original line number Diff line number Diff line
@@ -44,12 +44,14 @@ public:
    uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
    uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
    uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
    uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}

    uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}
    uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
    uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
    uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const;

    uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const;

    uint32_t getLODCount() const {return mLODCount;}
    bool getIsNp2() const;