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

Commit be1b127c authored by Romain Guy's avatar Romain Guy
Browse files

Assume a texture is unbound after deleting it

Bug #9316260

The GL specification indicates that deleting a bound texture has
the side effect of binding the default texture (name=0). This change
replaces all calls to glDeleteTextures() by Caches::deleteTexture()
to properly keep track of texture bindings.

Change-Id: Ifbc60ef433e0f9776a668dd5bd5f0adbc65a77a0
parent f6991305
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -508,6 +508,28 @@ void Caches::bindTexture(GLenum target, GLuint texture) {
    }
}

void Caches::deleteTexture(GLuint texture) {
    // When glDeleteTextures() is called on a currently bound texture,
    // OpenGL ES specifies that the texture is then considered unbound
    // Consider the following series of calls:
    //
    // glGenTextures -> creates texture name 2
    // glBindTexture(2)
    // glDeleteTextures(2) -> 2 is now unbound
    // glGenTextures -> can return 2 again
    //
    // If we don't call glBindTexture(2) after the second glGenTextures
    // call, any texture operation will be performed on the default
    // texture (name=0)

    for (int i = 0; i < REQUIRED_TEXTURE_UNITS_COUNT; i++) {
        if (mBoundTextures[i] == texture) {
            mBoundTextures[i] = 0;
        }
    }
    glDeleteTextures(1, &texture);
}

void Caches::resetBoundTextures() {
    memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint));
}
+12 −1
Original line number Diff line number Diff line
@@ -226,14 +226,25 @@ public:

    /**
     * Binds the specified texture as a GL_TEXTURE_2D texture.
     * All texture bindings must be performed with this method or
     * bindTexture(GLenum, GLuint).
     */
    void bindTexture(GLuint texture);

    /**
     * Binds the specified texture..
     * Binds the specified texture with the specified render target.
     * All texture bindings must be performed with this method or
     * bindTexture(GLuint).
     */
    void bindTexture(GLenum target, GLuint texture);

    /**
     * Deletes the specified texture and clears it from the cache
     * of bound textures.
     * All textures must be deleted using this method.
     */
    void deleteTexture(GLuint texture);

    /**
     * Signals that the cache of bound textures should be cleared.
     * Other users of the context may have altered which textures are bound.
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ void Dither::bindDitherTexture() {

void Dither::clear() {
    if (mInitialized) {
        glDeleteTextures(1, &mDitherTexture);
        mCaches->deleteTexture(mDitherTexture);
        mInitialized = false;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
        const uint32_t size = texture->width * texture->height * bytesPerPixel();
        mSize -= size;

        glDeleteTextures(1, &texture->id);
        texture->deleteTexture();
        delete texture;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ Image::~Image() {
        eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), mImage);
        mImage = EGL_NO_IMAGE_KHR;

        glDeleteTextures(1, &mTexture);
        Caches::getInstance().deleteTexture(mTexture);
        mTexture = 0;
    }
}
Loading