Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
{
    IDirect3DDevice9 *device = getDevice();
    IDirect3DSurface9 *surface = NULL;
    D3DSURFACE_DESC description;
    renderTarget->GetDesc(&description);
    
    HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);

    if (!SUCCEEDED(result))
    {
        ERR("Could not create matching destination surface.");
        return error(GL_OUT_OF_MEMORY);
    }

    result = device->GetRenderTargetData(renderTarget, surface);

    if (!SUCCEEDED(result))
    {
        ERR("GetRenderTargetData unexpectedly failed.");
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }

    D3DLOCKED_RECT sourceLock = {0};
    RECT sourceRect = {x, y, x + width, y + height};
    result = surface->LockRect(&sourceLock, &sourceRect, 0);

    if (FAILED(result))
    {
        ERR("Failed to lock the source surface (rectangle might be invalid).");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }

    if (!image->surface)
    {
        createSurface(width, height, internalFormat, mType, image);
    }

    if (image->surface == NULL)
    {
        ERR("Failed to create an image surface.");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY); 
    }

    D3DLOCKED_RECT destLock = {0};
    RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
    result = image->surface->LockRect(&destLock, &destRect, 0);
    
    if (FAILED(result))
    {
        ERR("Failed to lock the destination surface (rectangle might be invalid).");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }

    if (destLock.pBits && sourceLock.pBits)
    {
        unsigned char *source = (unsigned char*)sourceLock.pBits;
        unsigned char *dest = (unsigned char*)destLock.pBits;

        switch (description.Format)
        {
          case D3DFMT_X8R8G8B8:
          case D3DFMT_A8R8G8B8:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        dest[x] = source[x * 4 + 2];
                    }

                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              case D3DFMT_A8L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        dest[x * 2 + 0] = source[x * 4 + 2];
                        dest[x * 2 + 1] = source[x * 4 + 3];
                    }

                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          case D3DFMT_R5G6B5:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0xF8;
                        dest[x] = red | (red >> 5);
                    }

                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          case D3DFMT_A1R5G5B5:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0x7C;
                        dest[x] = (red << 1) | (red >> 4);
                    }

                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              case D3DFMT_A8L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0x7C;
                        dest[x * 2 + 0] = (red << 1) | (red >> 4);
                        dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
                    }

                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          default:
            UNREACHABLE();
        }

        image->dirty = true;
        mDirtyMetaData = true;    
    }

    image->surface->UnlockRect();
    surface->UnlockRect();
    surface->Release();
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
This implements glCopyTex [ Sub ] Image2D for non - renderable internal texture formats
void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
{
    IDirect3DDevice9 *device = getDevice();
    IDirect3DSurface9 *surface = NULL;
    D3DSURFACE_DESC description;
    renderTarget->GetDesc(&description);
    HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
    if (!SUCCEEDED(result))
    {
        ERR("Could not create matching destination surface.");
        return error(GL_OUT_OF_MEMORY);
    }
    result = device->GetRenderTargetData(renderTarget, surface);
    if (!SUCCEEDED(result))
    {
        ERR("GetRenderTargetData unexpectedly failed.");
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }
    D3DLOCKED_RECT sourceLock = {0};
    RECT sourceRect = {x, y, x + width, y + height};
    result = surface->LockRect(&sourceLock, &sourceRect, 0);
    if (FAILED(result))
    {
        ERR("Failed to lock the source surface (rectangle might be invalid).");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }
    if (!image->surface)
    {
        createSurface(width, height, internalFormat, mType, image);
    }
    if (image->surface == NULL)
    {
        ERR("Failed to create an image surface.");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY); 
    }
    D3DLOCKED_RECT destLock = {0};
    RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
    result = image->surface->LockRect(&destLock, &destRect, 0);
    if (FAILED(result))
    {
        ERR("Failed to lock the destination surface (rectangle might be invalid).");
        surface->UnlockRect();
        surface->Release();
        return error(GL_OUT_OF_MEMORY);
    }
    if (destLock.pBits && sourceLock.pBits)
    {
        unsigned char *source = (unsigned char*)sourceLock.pBits;
        unsigned char *dest = (unsigned char*)destLock.pBits;
        switch (description.Format)
        {
          case D3DFMT_X8R8G8B8:
          case D3DFMT_A8R8G8B8:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        dest[x] = source[x * 4 + 2];
                    }
                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              case D3DFMT_A8L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        dest[x * 2 + 0] = source[x * 4 + 2];
                        dest[x * 2 + 1] = source[x * 4 + 3];
                    }
                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          case D3DFMT_R5G6B5:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0xF8;
                        dest[x] = red | (red >> 5);
                    }
                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          case D3DFMT_A1R5G5B5:
            switch(getD3DFormat())
            {
              case D3DFMT_L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0x7C;
                        dest[x] = (red << 1) | (red >> 4);
                    }
                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              case D3DFMT_A8L8:
                for(int y = 0; y < height; y++)
                {
                    for(int x = 0; x < width; x++)
                    {
                        unsigned char red = source[x * 2 + 1] & 0x7C;
                        dest[x * 2 + 0] = (red << 1) | (red >> 4);
                        dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
                    }
                    source += sourceLock.Pitch;
                    dest += destLock.Pitch;
                }
                break;
              default:
                UNREACHABLE();
            }
            break;
          default:
            UNREACHABLE();
        }
        image->dirty = true;
        mDirtyMetaData = true;    
    }
    image->surface->UnlockRect();
    surface->UnlockRect();
    surface->Release();
}
void Texture :: copyNonRenderable ( Image * image , GLenum internalFormat , GLint xoffset , GLint yoffset , GLint x , GLint y , GLsizei width , GLsizei height , IDirect3DSurface9 * renderTarget ) { IDirect3DDevice9 * device = getDevice ( ) ; IDirect3DSurface9 * surface = NULL ; D3DSURFACE_DESC description ; renderTarget -> GetDesc ( & description ) ; HRESULT result = device -> CreateOffscreenPlainSurface ( description . Width , description . Height , description . Format , D3DPOOL_SYSTEMMEM , & surface , NULL ) ; if ( ! SUCCEEDED ( result ) ) { ERR ( " " ) ; return error ( GL_OUT_OF_MEMORY ) ; } result = device -> GetRenderTargetData ( renderTarget , surface ) ; if ( ! SUCCEEDED ( result ) ) { ERR ( " " ) ; surface -> Release ( ) ; return error ( GL_OUT_OF_MEMORY ) ; } D3DLOCKED_RECT sourceLock = { 0 } ; RECT sourceRect = { x , y , x + width , y + height } ; result = surface -> LockRect ( & sourceLock , & sourceRect , 0 ) ; if ( FAILED ( result ) ) { ERR ( " " ) ; surface -> UnlockRect ( ) ; surface -> Release ( ) ; return error ( GL_OUT_OF_MEMORY ) ; } if ( ! image -> surface ) { createSurface ( width , height , internalFormat , mType , image ) ; } if ( image -> surface == NULL ) { ERR ( " " ) ; surface -> UnlockRect ( ) ; surface -> Release ( ) ; return error ( GL_OUT_OF_MEMORY ) ; } D3DLOCKED_RECT destLock = { 0 } ; RECT destRect = { xoffset , yoffset , xoffset + width , yoffset + height } ; result = image -> surface -> LockRect ( & destLock , & destRect , 0 ) ; if ( FAILED ( result ) ) { ERR ( " " ) ; surface -> UnlockRect ( ) ; surface -> Release ( ) ; return error ( GL_OUT_OF_MEMORY ) ; } if ( destLock . pBits && sourceLock . pBits ) { unsigned char * source = ( unsigned char * ) sourceLock . pBits ; unsigned char * dest = ( unsigned char * ) destLock . pBits ; switch ( description . Format ) { case D3DFMT_X8R8G8B8 : case D3DFMT_A8R8G8B8 : switch ( getD3DFormat ( ) ) { case D3DFMT_L8 : for ( int y = 0 ; y < height ; y ++ ) { for ( int x = 0 ; x < width ; x ++ ) { dest [ x ] = source [ x * 4 + 2 ] ; } source += sourceLock . Pitch ; dest += destLock . Pitch ; } break ; case D3DFMT_A8L8 : for ( int y = 0 ; y < height ; y ++ ) { for ( int x = 0 ; x < width ; x ++ ) { dest [ x * 2 + 0 ] = source [ x * 4 + 2 ] ; dest [ x * 2 + 1 ] = source [ x * 4 + 3 ] ; } source += sourceLock . Pitch ; dest += destLock . Pitch ; } break ; default : UNREACHABLE ( ) ; } break ; case D3DFMT_R5G6B5 : switch ( getD3DFormat ( ) ) { case D3DFMT_L8 : for ( int y = 0 ; y < height ; y ++ ) { for ( int x = 0 ; x < width ; x ++ ) { unsigned char red = source [ x * 2 + 1 ] & 0xF8 ; dest [ x ] = red | ( red >> 5 ) ; } source += sourceLock . Pitch ; dest += destLock . Pitch ; } break ; default : UNREACHABLE ( ) ; } break ; case D3DFMT_A1R5G5B5 : switch ( getD3DFormat ( ) ) { case D3DFMT_L8 : for ( int y = 0 ; y < height ; y ++ ) { for ( int x = 0 ; x < width ; x ++ ) { unsigned char red = source [ x * 2 + 1 ] & 0x7C ; dest [ x ] = ( red << 1 ) | ( red >> 4 ) ; } source += sourceLock . Pitch ; dest += destLock . Pitch ; } break ; case D3DFMT_A8L8 : for ( int y = 0 ; y < height ; y ++ ) { for ( int x = 0 ; x < width ; x ++ ) { unsigned char red = source [ x * 2 + 1 ] & 0x7C ; dest [ x * 2 + 0 ] = ( red << 1 ) | ( red >> 4 ) ; dest [ x * 2 + 1 ] = ( signed char ) source [ x * 2 + 1 ] >> 7 ; } source += sourceLock . Pitch ; dest += destLock . Pitch ; } break ; default : UNREACHABLE ( ) ; } break ; default : UNREACHABLE ( ) ; } image -> dirty = true ; mDirtyMetaData = true ; } image -> surface -> UnlockRect ( ) ; surface -> UnlockRect ( ) ; surface -> Release ( ) ; }
This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
This implements glCopyTex [ Sub ] Image2D for non - renderable internal texture formats