Added resize support for GDI and Direct3D renderers
authorSam Lantinga <slouken@libsdl.org>
Mon, 07 Aug 2006 05:24:13 +0000
changeset 1975ccef0d0c40c6
parent 1974 70deaf574153
child 1976 b1620a317791
Added resize support for GDI and Direct3D renderers
src/video/SDL_renderer_gl.c
src/video/win32/SDL_d3drender.c
src/video/win32/SDL_gdirender.c
     1.1 --- a/src/video/SDL_renderer_gl.c	Sun Aug 06 23:34:59 2006 +0000
     1.2 +++ b/src/video/SDL_renderer_gl.c	Mon Aug 07 05:24:13 2006 +0000
     1.3 @@ -789,7 +789,7 @@
     1.4      texture->driverdata = NULL;
     1.5  }
     1.6  
     1.7 -void
     1.8 +static void
     1.9  GL_DestroyRenderer(SDL_Renderer * renderer)
    1.10  {
    1.11      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
     2.1 --- a/src/video/win32/SDL_d3drender.c	Sun Aug 06 23:34:59 2006 +0000
     2.2 +++ b/src/video/win32/SDL_d3drender.c	Mon Aug 07 05:24:13 2006 +0000
     2.3 @@ -28,6 +28,7 @@
     2.4  /* Direct3D renderer implementation */
     2.5  
     2.6  static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
     2.7 +static int D3D_DisplayModeChanged(SDL_Renderer * renderer);
     2.8  static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     2.9  static int D3D_SetTexturePalette(SDL_Renderer * renderer,
    2.10                                   SDL_Texture * texture,
    2.11 @@ -61,7 +62,7 @@
    2.12      {
    2.13       "d3d",
    2.14       (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
    2.15 -      SDL_RENDERER_PRESENTFLIP2 | sDL_RENDERER_PRESENTFLIP3 |
    2.16 +      SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    2.17        SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC |
    2.18        SDL_RENDERER_ACCELERATED),
    2.19       (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
    2.20 @@ -90,6 +91,7 @@
    2.21  typedef struct
    2.22  {
    2.23      IDirect3DDevice9 *device;
    2.24 +    D3DPRESENT_PARAMETERS pparams;
    2.25      SDL_bool beginScene;
    2.26  } D3D_RenderData;
    2.27  
    2.28 @@ -182,6 +184,7 @@
    2.29          break;
    2.30      }
    2.31      SDL_SetError("%s: %s", prefix, error);
    2.32 +    fprintf(stderr, "%s: %s\n", prefix, error);
    2.33  }
    2.34  
    2.35  static D3DFORMAT
    2.36 @@ -253,6 +256,7 @@
    2.37          return NULL;
    2.38      }
    2.39  
    2.40 +    renderer->DisplayModeChanged = D3D_DisplayModeChanged;
    2.41      renderer->CreateTexture = D3D_CreateTexture;
    2.42      renderer->SetTexturePalette = D3D_SetTexturePalette;
    2.43      renderer->GetTexturePalette = D3D_GetTexturePalette;
    2.44 @@ -276,7 +280,7 @@
    2.45      pparams.BackBufferHeight = window->h;
    2.46      if (window->flags & SDL_WINDOW_FULLSCREEN) {
    2.47          pparams.BackBufferFormat =
    2.48 -            PixelFormatToD3DFMT(display->fullscreen_mode->format);
    2.49 +            PixelFormatToD3DFMT(display->fullscreen_mode.format);
    2.50      } else {
    2.51          pparams.BackBufferFormat = D3DFMT_UNKNOWN;
    2.52      }
    2.53 @@ -296,7 +300,7 @@
    2.54      if (window->flags & SDL_WINDOW_FULLSCREEN) {
    2.55          pparams.Windowed = FALSE;
    2.56          pparams.FullScreen_RefreshRateInHz =
    2.57 -            display->fullscreen_mode->refresh_rate;
    2.58 +            display->fullscreen_mode.refresh_rate;
    2.59      } else {
    2.60          pparams.Windowed = TRUE;
    2.61          pparams.FullScreen_RefreshRateInHz = 0;
    2.62 @@ -355,6 +359,7 @@
    2.63      if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
    2.64          renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
    2.65      }
    2.66 +    data->pparams = pparams;
    2.67  
    2.68      IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
    2.69      renderer->info.max_texture_width = caps.MaxTextureWidth;
    2.70 @@ -371,6 +376,48 @@
    2.71  }
    2.72  
    2.73  static int
    2.74 +D3D_Reset(SDL_Renderer * renderer)
    2.75 +{
    2.76 +    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    2.77 +    HRESULT result;
    2.78 +
    2.79 +    result = IDirect3DDevice9_Reset(data->device, &data->pparams);
    2.80 +    if (FAILED(result)) {
    2.81 +        if (result == D3DERR_DEVICELOST) {
    2.82 +            /* Don't worry about it, we'll reset later... */
    2.83 +            return 0;
    2.84 +        } else {
    2.85 +            D3D_SetError("Reset()", result);
    2.86 +            return -1;
    2.87 +        }
    2.88 +    }
    2.89 +    IDirect3DDevice9_SetVertexShader(data->device, NULL);
    2.90 +    IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_TEX1);
    2.91 +    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
    2.92 +                                    D3DCULL_NONE);
    2.93 +    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
    2.94 +    return 0;
    2.95 +}
    2.96 +
    2.97 +static int
    2.98 +D3D_DisplayModeChanged(SDL_Renderer * renderer)
    2.99 +{
   2.100 +    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
   2.101 +    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   2.102 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   2.103 +
   2.104 +    data->pparams.BackBufferWidth = window->w;
   2.105 +    data->pparams.BackBufferHeight = window->h;
   2.106 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   2.107 +        data->pparams.BackBufferFormat =
   2.108 +            PixelFormatToD3DFMT(display->fullscreen_mode.format);
   2.109 +    } else {
   2.110 +        data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
   2.111 +    }
   2.112 +    return D3D_Reset(renderer);
   2.113 +}
   2.114 +
   2.115 +static int
   2.116  D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   2.117  {
   2.118      D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
   2.119 @@ -388,6 +435,12 @@
   2.120  
   2.121      texture->driverdata = data;
   2.122  
   2.123 +#if 1
   2.124 +    /* FIXME: Do we want non-managed textures?
   2.125 +       They need to be freed on device reset and then reloaded by the app...
   2.126 +     */
   2.127 +    texture->access = SDL_TEXTUREACCESS_LOCAL;
   2.128 +#endif
   2.129      if (texture->access == SDL_TEXTUREACCESS_LOCAL) {
   2.130          pool = D3DPOOL_MANAGED;
   2.131      } else {
   2.132 @@ -709,6 +762,14 @@
   2.133          data->beginScene = SDL_TRUE;
   2.134      }
   2.135  
   2.136 +    result = IDirect3DDevice9_TestCooperativeLevel(data->device);
   2.137 +    if (result == D3DERR_DEVICELOST) {
   2.138 +        /* We'll reset later */
   2.139 +        return;
   2.140 +    }
   2.141 +    if (result == D3DERR_DEVICENOTRESET) {
   2.142 +        D3D_Reset(renderer);
   2.143 +    }
   2.144      result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
   2.145      if (FAILED(result)) {
   2.146          D3D_SetError("Present()", result);
   2.147 @@ -730,7 +791,7 @@
   2.148      texture->driverdata = NULL;
   2.149  }
   2.150  
   2.151 -void
   2.152 +static void
   2.153  D3D_DestroyRenderer(SDL_Renderer * renderer)
   2.154  {
   2.155      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
     3.1 --- a/src/video/win32/SDL_gdirender.c	Sun Aug 06 23:34:59 2006 +0000
     3.2 +++ b/src/video/win32/SDL_gdirender.c	Mon Aug 07 05:24:13 2006 +0000
     3.3 @@ -30,6 +30,7 @@
     3.4  /* GDI renderer implementation */
     3.5  
     3.6  static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags);
     3.7 +static int GDI_DisplayModeChanged(SDL_Renderer * renderer);
     3.8  static int GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     3.9  static int GDI_QueryTexturePixels(SDL_Renderer * renderer,
    3.10                                    SDL_Texture * texture, void **pixels,
    3.11 @@ -66,7 +67,7 @@
    3.12      {
    3.13       "gdi",
    3.14       (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
    3.15 -      SDL_RENDERER_PRESENTFLIP2 | sDL_RENDERER_PRESENTFLIP3 |
    3.16 +      SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    3.17        SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
    3.18       (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
    3.19        SDL_TEXTUREBLENDMODE_BLEND),
    3.20 @@ -155,6 +156,7 @@
    3.21          return NULL;
    3.22      }
    3.23  
    3.24 +    renderer->DisplayModeChanged = GDI_DisplayModeChanged;
    3.25      renderer->CreateTexture = GDI_CreateTexture;
    3.26      renderer->QueryTexturePixels = GDI_QueryTexturePixels;
    3.27      renderer->SetTexturePalette = GDI_SetTexturePalette;
    3.28 @@ -196,7 +198,7 @@
    3.29  
    3.30      if (flags & SDL_RENDERER_SINGLEBUFFER) {
    3.31          renderer->info.flags |=
    3.32 -            (SDL_RENDERER_SINGLEBUFFER | sDL_RENDERER_PRESENTCOPY);
    3.33 +            (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY);
    3.34          n = 0;
    3.35      } else if (flags & SDL_RENDERER_PRESENTFLIP2) {
    3.36          renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
    3.37 @@ -231,6 +233,42 @@
    3.38  }
    3.39  
    3.40  static int
    3.41 +GDI_DisplayModeChanged(SDL_Renderer * renderer)
    3.42 +{
    3.43 +    GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
    3.44 +    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
    3.45 +    int i, n;
    3.46 +
    3.47 +    if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) {
    3.48 +        n = 0;
    3.49 +    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
    3.50 +        n = 2;
    3.51 +    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
    3.52 +        n = 3;
    3.53 +    } else {
    3.54 +        n = 1;
    3.55 +    }
    3.56 +    for (i = 0; i < n; ++i) {
    3.57 +        if (data->hbm[i]) {
    3.58 +            DeleteObject(data->hbm[i]);
    3.59 +            data->hbm[i] = NULL;
    3.60 +        }
    3.61 +    }
    3.62 +    for (i = 0; i < n; ++i) {
    3.63 +        data->hbm[i] =
    3.64 +            CreateCompatibleBitmap(data->window_hdc, window->w, window->h);
    3.65 +        if (!data->hbm[i]) {
    3.66 +            WIN_SetError("CreateCompatibleBitmap()");
    3.67 +            return -1;
    3.68 +        }
    3.69 +    }
    3.70 +    if (n > 0) {
    3.71 +        SelectObject(data->render_hdc, data->hbm[0]);
    3.72 +    }
    3.73 +    return 0;
    3.74 +}
    3.75 +
    3.76 +static int
    3.77  GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    3.78  {
    3.79      GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata;
    3.80 @@ -258,7 +296,7 @@
    3.81      data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
    3.82  
    3.83      if (data->yuv || texture->access == SDL_TEXTUREACCESS_LOCAL
    3.84 -        || texture->format != SDL_GetCurrentDisplayMode()->format) {
    3.85 +        || texture->format != display->current_mode.format) {
    3.86          int bmi_size;
    3.87          LPBITMAPINFO bmi;
    3.88  
    3.89 @@ -621,7 +659,7 @@
    3.90      texture->driverdata = NULL;
    3.91  }
    3.92  
    3.93 -void
    3.94 +static void
    3.95  GDI_DestroyRenderer(SDL_Renderer * renderer)
    3.96  {
    3.97      GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;