Search code examples
memorysdl-2

Why am I having "LockRect(): INVALIDCALL" in SDL_UpdateTexture?


Windows 10.

MSYS2 MinGW 64bit.

SDL2.

I'm updating a streaming texture using pixel data from a surface. Both have same size and same pixel format. Below code return error "LockRect(): INVALIDCALL" when calling "SDL_UpdateTexture":

    // this->tex is a class private pointer to a SDL_Texture
    // this->sur is a class private pointer to a SDL_Surface
    // Update the texture with the surface
    // lock the texture
    void *texPixels;
    int pitch;
    if (SDL_LockTexture(this->tex, NULL, &texPixels, &pitch) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock texture: %s\n", SDL_GetError());
    }
    // Get the pixels information from the surface
    void *surPixels = this->sur->pixels;
    int surPitch = this->sur->pitch;
    // update the texture with the pixels from the surface
    if (SDL_UpdateTexture(this->tex, NULL, surPixels, surPitch) < 0){
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't Update texture: %s\n", SDL_GetError());
    }
    // unlock the texture
    SDL_UnlockTexture(this->tex);

So I decided to just copy the pixels this way:

    // this->tex is a pointer to a SDL_Texture
    // this->sur is a pointer to a SDL_Surface
    // Update the texture with the surface
    // lock the texture
    void *texPixels;
    int pitch;
    if (SDL_LockTexture(this->tex, NULL, &texPixels, &pitch) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock texture: %s\n", SDL_GetError());
    }
    // Get the pixels information from the surface
    void *surPixels = this->sur->pixels;
    int surPitch = this->sur->pitch;
    // update the texture with the pixels from the surface
    memcpy(texPixels, surPixels, (surPitch * this->sur->h));    
    // unlock the texture
    SDL_UnlockTexture(this->tex);

And this works perfectly. So, my question is: Why is failing "SDL_UpdateTexture"? What am I doing wrong?

Second question, but less important: is my solution to this problem OK?


Solution

  • Your second code fragment is how you supposed to update streaming texture. Lock means "give me memory to write pixels into, I'll unlock when I'm done". UpdateTexture conflicts with that - you ask SDL to perform an update, but texture is already locked by you. If it didn't fail with error, result would be even worse - your unlock would have just written garbage data because you haven't modified pixel array. You can use UpdateTexture without Lock/Unlock, but it may be less efficient for streaming, in some renderer implementations.