src/video/directfb/SDL_DirectFB_render.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 13 Oct 2014 10:46:27 -0700
changeset 9156 f68bd6205580
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Minor cleanups
slouken@2226
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@2226
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@2226
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@2226
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@2226
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@6044
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_DIRECTFB
slouken@5199
    24
#include "SDL_DirectFB_window.h"
slouken@5199
    25
#include "SDL_DirectFB_modes.h"
slouken@2226
    26
slouken@5488
    27
#include "SDL_syswm.h"
slouken@5199
    28
#include "SDL_DirectFB_shape.h"
slouken@5199
    29
slouken@5199
    30
#include "../SDL_sysvideo.h"
slouken@5199
    31
#include "../../render/SDL_sysrender.h"
slouken@2226
    32
slouken@5488
    33
#ifndef DFB_VERSION_ATLEAST
slouken@5488
    34
slouken@6989
    35
#define DFB_VERSIONNUM(X, Y, Z)                     \
slouken@6989
    36
    ((X)*1000 + (Y)*100 + (Z))
slouken@5488
    37
slouken@5488
    38
#define DFB_COMPILEDVERSION \
slouken@6989
    39
    DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
slouken@5488
    40
slouken@5488
    41
#define DFB_VERSION_ATLEAST(X, Y, Z) \
slouken@6989
    42
    (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
slouken@5488
    43
slouken@6989
    44
#define SDL_DFB_CHECK(x)    x
slouken@5488
    45
slouken@5488
    46
#endif
slouken@5488
    47
slouken@2737
    48
/* the following is not yet tested ... */
slouken@6989
    49
#define USE_DISPLAY_PALETTE         (0)
slouken@2737
    50
slouken@5199
    51
slouken@5199
    52
#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
slouken@5199
    53
slouken@5199
    54
slouken@9156
    55
/* DirectFB renderer implementation */
slouken@2226
    56
slouken@2226
    57
static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
slouken@2226
    58
                                             Uint32 flags);
slouken@5199
    59
static void DirectFB_ActivateRenderer(SDL_Renderer * renderer);
slouken@2226
    60
static int DirectFB_CreateTexture(SDL_Renderer * renderer,
slouken@2226
    61
                                  SDL_Texture * texture);
slouken@2226
    62
static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
couriersud@3023
    63
                                       SDL_Texture * texture,
couriersud@3023
    64
                                       void **pixels, int *pitch);
slouken@5199
    65
static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
slouken@5199
    66
                                      SDL_Texture * texture,
slouken@5199
    67
                                      const SDL_Color * colors,
slouken@5199
    68
                                      int firstcolor, int ncolors);
slouken@5199
    69
static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
slouken@5199
    70
                                      SDL_Texture * texture,
slouken@5199
    71
                                      SDL_Color * colors,
slouken@5199
    72
                                      int firstcolor, int ncolors);
slouken@5199
    73
static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
slouken@5199
    74
                                       SDL_Texture * texture);
slouken@5199
    75
static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
slouken@5199
    76
                                       SDL_Texture * texture);
slouken@5199
    77
static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
slouken@5199
    78
                                        SDL_Texture * texture);
slouken@5199
    79
static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
slouken@5199
    80
                                        SDL_Texture * texture);
slouken@2226
    81
static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
slouken@2226
    82
                                  SDL_Texture * texture,
couriersud@3023
    83
                                  const SDL_Rect * rect,
couriersud@3023
    84
                                  const void *pixels, int pitch);
slouken@2226
    85
static int DirectFB_LockTexture(SDL_Renderer * renderer,
couriersud@3023
    86
                                SDL_Texture * texture,
slouken@5199
    87
                                const SDL_Rect * rect,
couriersud@3023
    88
                                void **pixels, int *pitch);
slouken@2226
    89
static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
slouken@2226
    90
                                   SDL_Texture * texture);
slouken@2226
    91
static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
slouken@2226
    92
                                  SDL_Texture * texture, int numrects,
slouken@2226
    93
                                  const SDL_Rect * rects);
slouken@5199
    94
static int DirectFB_SetDrawBlendMode(SDL_Renderer * renderer);
couriersud@3640
    95
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
slouken@6986
    96
                                const SDL_FPoint * points, int count);
couriersud@3640
    97
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
slouken@6986
    98
                               const SDL_FPoint * points, int count);
slouken@5199
    99
static int DirectFB_RenderDrawRects(SDL_Renderer * renderer,
slouken@6989
   100
        const SDL_Rect ** rects, int count);
couriersud@3640
   101
static int DirectFB_RenderFillRects(SDL_Renderer * renderer,
slouken@6989
   102
        const SDL_FRect * rects, int count);
couriersud@3023
   103
static int DirectFB_RenderCopy(SDL_Renderer * renderer,
couriersud@3023
   104
                               SDL_Texture * texture,
slouken@2226
   105
                               const SDL_Rect * srcrect,
slouken@6986
   106
                               const SDL_FRect * dstrect);
slouken@2226
   107
static void DirectFB_RenderPresent(SDL_Renderer * renderer);
slouken@2226
   108
static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
slouken@2226
   109
                                    SDL_Texture * texture);
slouken@2226
   110
static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
slouken@5199
   111
static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@5199
   112
                     Uint32 format, void * pixels, int pitch);
slouken@5199
   113
static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@5199
   114
                      Uint32 format, const void * pixels, int pitch);
slouken@5488
   115
static int DirectFB_UpdateViewport(SDL_Renderer * renderer);
slouken@7141
   116
static int DirectFB_UpdateClipRect(SDL_Renderer * renderer);
slouken@6989
   117
static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@5488
   118
slouken@5488
   119
static int PrepareDraw(SDL_Renderer * renderer);
slouken@5199
   120
slouken@2226
   121
couriersud@3038
   122
#define SDL_DFB_WINDOWSURFACE(win)  IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
couriersud@3038
   123
slouken@2226
   124
SDL_RenderDriver DirectFB_RenderDriver = {
slouken@2226
   125
    DirectFB_CreateRenderer,
slouken@2226
   126
    {
slouken@2226
   127
     "directfb",
slouken@5142
   128
     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
slouken@5199
   129
     /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
slouken@5199
   130
      SDL_TEXTUREMODULATE_ALPHA),
slouken@5199
   131
      (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
slouken@5199
   132
      SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
slouken@5199
   133
     (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST |
gabomdq@7677
   134
      SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), */
slouken@5199
   135
     0,
slouken@2226
   136
     {
slouken@6989
   137
             /* formats filled in later */
slouken@5199
   138
     },
slouken@2226
   139
     0,
slouken@2226
   140
     0}
slouken@2226
   141
};
slouken@2226
   142
slouken@2226
   143
typedef struct
slouken@2226
   144
{
couriersud@3038
   145
    SDL_Window *window;
slouken@2226
   146
    DFBSurfaceFlipFlags flipflags;
slouken@2737
   147
    int size_changed;
slouken@2884
   148
    int lastBlendMode;
slouken@2884
   149
    DFBSurfaceBlittingFlags blitFlags;
slouken@2884
   150
    DFBSurfaceDrawingFlags drawFlags;
slouken@6989
   151
    IDirectFBSurface* target;
slouken@2226
   152
} DirectFB_RenderData;
slouken@2226
   153
slouken@2226
   154
typedef struct
slouken@2226
   155
{
slouken@2226
   156
    IDirectFBSurface *surface;
slouken@2226
   157
    Uint32 format;
slouken@2226
   158
    void *pixels;
slouken@2226
   159
    int pitch;
slouken@5199
   160
    IDirectFBPalette *palette;
slouken@5199
   161
    int isDirty;
slouken@5199
   162
slouken@5199
   163
    SDL_VideoDisplay *display;      /* only for yuv textures */
slouken@5199
   164
couriersud@3037
   165
#if (DFB_VERSION_ATLEAST(1,2,0))
slouken@2737
   166
    DFBSurfaceRenderOptions render_options;
slouken@2737
   167
#endif
slouken@2226
   168
} DirectFB_TextureData;
slouken@2226
   169
slouken@7860
   170
static SDL_INLINE void
slouken@2737
   171
SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
slouken@2737
   172
{
slouken@2737
   173
    dr->x = sr->x;
slouken@2737
   174
    dr->y = sr->y;
slouken@2737
   175
    dr->h = sr->h;
slouken@2737
   176
    dr->w = sr->w;
slouken@2737
   177
}
slouken@7860
   178
static SDL_INLINE void
slouken@6986
   179
SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr)
slouken@6986
   180
{
slouken@6986
   181
    dr->x = sr->x;
slouken@6986
   182
    dr->y = sr->y;
slouken@6986
   183
    dr->h = sr->h;
slouken@6986
   184
    dr->w = sr->w;
slouken@6986
   185
}
slouken@2737
   186
slouken@2884
   187
slouken@2884
   188
static int
slouken@2884
   189
TextureHasAlpha(DirectFB_TextureData * data)
slouken@2884
   190
{
slouken@2884
   191
    /* Drawing primitive ? */
slouken@2884
   192
    if (!data)
slouken@2884
   193
        return 0;
slouken@6989
   194
slouken@5199
   195
    return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0);
slouken@5199
   196
#if 0
slouken@2884
   197
    switch (data->format) {
slouken@5199
   198
    case SDL_PIXELFORMAT_INDEX4LSB:
slouken@5199
   199
    case SDL_PIXELFORMAT_INDEX4MSB:
slouken@2884
   200
    case SDL_PIXELFORMAT_ARGB4444:
slouken@2884
   201
    case SDL_PIXELFORMAT_ARGB1555:
slouken@2884
   202
    case SDL_PIXELFORMAT_ARGB8888:
slouken@2884
   203
    case SDL_PIXELFORMAT_RGBA8888:
slouken@2884
   204
    case SDL_PIXELFORMAT_ABGR8888:
slouken@2884
   205
    case SDL_PIXELFORMAT_BGRA8888:
slouken@2884
   206
    case SDL_PIXELFORMAT_ARGB2101010:
slouken@5199
   207
       return 1;
slouken@2884
   208
    default:
slouken@2884
   209
        return 0;
slouken@2884
   210
    }
slouken@5199
   211
#endif
slouken@2884
   212
}
slouken@2884
   213
slouken@7860
   214
static SDL_INLINE IDirectFBSurface *get_dfb_surface(SDL_Window *window)
slouken@5488
   215
{
slouken@6989
   216
    SDL_SysWMinfo wm_info;
slouken@6986
   217
    SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
slouken@6986
   218
slouken@6989
   219
    SDL_VERSION(&wm_info.version);
slouken@6989
   220
    SDL_GetWindowWMInfo(window, &wm_info);
slouken@5488
   221
slouken@6989
   222
    return wm_info.info.dfb.surface;
slouken@5488
   223
}
slouken@5488
   224
slouken@7860
   225
static SDL_INLINE IDirectFBWindow *get_dfb_window(SDL_Window *window)
slouken@5488
   226
{
slouken@6989
   227
    SDL_SysWMinfo wm_info;
slouken@6986
   228
    SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
slouken@6986
   229
slouken@6989
   230
    SDL_VERSION(&wm_info.version);
slouken@6989
   231
    SDL_GetWindowWMInfo(window, &wm_info);
slouken@5488
   232
slouken@6989
   233
    return wm_info.info.dfb.window;
slouken@5488
   234
}
slouken@5488
   235
slouken@2884
   236
static void
slouken@2884
   237
SetBlendMode(DirectFB_RenderData * data, int blendMode,
slouken@2884
   238
             DirectFB_TextureData * source)
slouken@2884
   239
{
slouken@6989
   240
    IDirectFBSurface *destsurf = data->target;
slouken@3040
   241
slouken@7191
   242
    /* FIXME: check for format change */
slouken@2884
   243
    if (1 || data->lastBlendMode != blendMode) {
slouken@2884
   244
        switch (blendMode) {
slouken@2884
   245
        case SDL_BLENDMODE_NONE:
slouken@2884
   246
                                           /**< No blending */
slouken@2884
   247
            data->blitFlags = DSBLIT_NOFX;
slouken@2884
   248
            data->drawFlags = DSDRAW_NOFX;
slouken@4636
   249
            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
slouken@4636
   250
            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
slouken@2884
   251
            break;
slouken@5199
   252
#if 0
slouken@5199
   253
        case SDL_BLENDMODE_MASK:
slouken@5199
   254
            data->blitFlags =  DSBLIT_BLEND_ALPHACHANNEL;
slouken@5199
   255
            data->drawFlags = DSDRAW_BLEND;
slouken@5199
   256
            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
slouken@5199
   257
            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
slouken@5199
   258
            break;
slouken@5199
   259
#endif
slouken@2884
   260
        case SDL_BLENDMODE_BLEND:
slouken@2884
   261
            data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
slouken@2884
   262
            data->drawFlags = DSDRAW_BLEND;
slouken@4636
   263
            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
slouken@4636
   264
            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
slouken@2884
   265
            break;
slouken@2884
   266
        case SDL_BLENDMODE_ADD:
slouken@2884
   267
            data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
slouken@2884
   268
            data->drawFlags = DSDRAW_BLEND;
slouken@7744
   269
            /* FIXME: SRCALPHA kills performance on radeon ...
slouken@7191
   270
             * It will be cheaper to copy the surface to a temporary surface and premultiply
slouken@7191
   271
             */
slouken@2930
   272
            if (source && TextureHasAlpha(source))
slouken@4636
   273
                SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
slouken@2884
   274
            else
slouken@4636
   275
                SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
slouken@4636
   276
            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
slouken@2884
   277
            break;
slouken@5199
   278
        case SDL_BLENDMODE_MOD:
slouken@5199
   279
            data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
slouken@5199
   280
            data->drawFlags = DSDRAW_BLEND;
slouken@5199
   281
            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
slouken@5199
   282
            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
slouken@5199
   283
slouken@5199
   284
            break;
slouken@2884
   285
        }
slouken@2884
   286
        data->lastBlendMode = blendMode;
slouken@2884
   287
    }
slouken@2884
   288
}
slouken@2884
   289
slouken@5199
   290
static int
slouken@5199
   291
DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
slouken@2226
   292
{
slouken@5199
   293
#if USE_DISPLAY_PALETTE
slouken@5199
   294
    DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
slouken@5199
   295
    SDL_DFB_WINDOWSURFACE(data->window);
slouken@5199
   296
    IDirectFBPalette *surfpal;
slouken@5199
   297
slouken@2226
   298
    int i;
slouken@5199
   299
    int ncolors;
slouken@5199
   300
    DFBColor entries[256];
slouken@3520
   301
slouken@5199
   302
    SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &surfpal));
slouken@5199
   303
slouken@5199
   304
    /* FIXME: number of colors */
slouken@5199
   305
    ncolors = (palette->ncolors < 256 ? palette->ncolors : 256);
slouken@5199
   306
slouken@5199
   307
    for (i = 0; i < ncolors; ++i) {
slouken@5199
   308
        entries[i].r = palette->colors[i].r;
slouken@5199
   309
        entries[i].g = palette->colors[i].g;
slouken@5199
   310
        entries[i].b = palette->colors[i].b;
philipp@7751
   311
        entries[i].a = palette->colors[i].a;
slouken@3520
   312
    }
slouken@5199
   313
    SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0));
slouken@5199
   314
    return 0;
slouken@5199
   315
  error:
slouken@5199
   316
#else
slouken@5199
   317
    SDL_Unsupported();
slouken@5199
   318
#endif
slouken@5199
   319
    return -1;
slouken@5199
   320
}
slouken@5199
   321
slouken@5199
   322
static void
slouken@5199
   323
DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
slouken@5199
   324
{
slouken@5199
   325
    SDL_DFB_RENDERERDATA(renderer);
slouken@5199
   326
slouken@5276
   327
    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
slouken@5199
   328
        /* Rebind the context to the window area and update matrices */
gabomdq@7678
   329
        /* SDL_CurrentContext = NULL; */
gabomdq@7678
   330
        /* data->updateSize = SDL_TRUE; */
slouken@5199
   331
        renddata->size_changed = SDL_TRUE;
slouken@5199
   332
   }
slouken@5199
   333
}
slouken@5199
   334
slouken@5199
   335
int
slouken@5199
   336
DirectFB_RenderClear(SDL_Renderer * renderer)
slouken@5199
   337
{
slouken@5488
   338
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   339
    IDirectFBSurface *destsurf = data->target;
slouken@5199
   340
slouken@5199
   341
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   342
slouken@5488
   343
    PrepareDraw(renderer);
slouken@5488
   344
slouken@5488
   345
    destsurf->Clear(destsurf, renderer->r, renderer->g, renderer->b, renderer->a);
slouken@5488
   346
slouken@5488
   347
slouken@5199
   348
    return 0;
slouken@2226
   349
}
slouken@2226
   350
slouken@2226
   351
SDL_Renderer *
slouken@2226
   352
DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
slouken@2226
   353
{
slouken@6989
   354
    IDirectFBSurface *winsurf = get_dfb_surface(window);
slouken@5246
   355
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@2226
   356
    SDL_Renderer *renderer = NULL;
slouken@2226
   357
    DirectFB_RenderData *data = NULL;
slouken@5199
   358
    DFBSurfaceCapabilities scaps;
slouken@2226
   359
slouken@5199
   360
    SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer));
slouken@5199
   361
    SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
slouken@2226
   362
slouken@5199
   363
    renderer->WindowEvent = DirectFB_WindowEvent;
slouken@2226
   364
    renderer->CreateTexture = DirectFB_CreateTexture;
slouken@5199
   365
    renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
slouken@5199
   366
    renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
slouken@5199
   367
    renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
slouken@2226
   368
    renderer->UpdateTexture = DirectFB_UpdateTexture;
slouken@2226
   369
    renderer->LockTexture = DirectFB_LockTexture;
slouken@5199
   370
    renderer->RenderClear = DirectFB_RenderClear;
slouken@2226
   371
    renderer->UnlockTexture = DirectFB_UnlockTexture;
couriersud@3640
   372
    renderer->RenderDrawPoints = DirectFB_RenderDrawPoints;
couriersud@3640
   373
    renderer->RenderDrawLines = DirectFB_RenderDrawLines;
slouken@5199
   374
    /* SetDrawColor - no needed */
couriersud@3640
   375
    renderer->RenderFillRects = DirectFB_RenderFillRects;
slouken@5488
   376
slouken@2226
   377
    renderer->RenderCopy = DirectFB_RenderCopy;
slouken@2226
   378
    renderer->RenderPresent = DirectFB_RenderPresent;
slouken@6989
   379
slouken@5199
   380
    /* FIXME: Yet to be tested */
slouken@5199
   381
    renderer->RenderReadPixels = DirectFB_RenderReadPixels;
gabomdq@7678
   382
    /* renderer->RenderWritePixels = DirectFB_RenderWritePixels; */
slouken@6989
   383
slouken@2226
   384
    renderer->DestroyTexture = DirectFB_DestroyTexture;
slouken@2226
   385
    renderer->DestroyRenderer = DirectFB_DestroyRenderer;
slouken@5488
   386
    renderer->UpdateViewport = DirectFB_UpdateViewport;
slouken@7141
   387
    renderer->UpdateClipRect = DirectFB_UpdateClipRect;
slouken@6989
   388
    renderer->SetRenderTarget = DirectFB_SetRenderTarget;
slouken@5199
   389
slouken@5199
   390
#if 0
slouken@5199
   391
    renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
slouken@5199
   392
    renderer->SetTexturePalette = DirectFB_SetTexturePalette;
slouken@5199
   393
    renderer->GetTexturePalette = DirectFB_GetTexturePalette;
slouken@5199
   394
    renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
slouken@5199
   395
    renderer->DirtyTexture = DirectFB_DirtyTexture;
slouken@5199
   396
    renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode;
slouken@5199
   397
    renderer->RenderDrawRects = DirectFB_RenderDrawRects;
slouken@5199
   398
#endif
slouken@5199
   399
slouken@2226
   400
    renderer->info = DirectFB_RenderDriver.info;
slouken@3685
   401
    renderer->window = window;      /* SDL window */
slouken@2226
   402
    renderer->driverdata = data;
slouken@2226
   403
slouken@5199
   404
    renderer->info.flags =
slouken@6989
   405
        SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
slouken@2226
   406
couriersud@3038
   407
    data->window = window;
slouken@6989
   408
    data->target = winsurf;
slouken@2737
   409
slouken@2737
   410
    data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
slouken@2226
   411
slouken@2226
   412
    if (flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@4636
   413
        data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
slouken@2226
   414
        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
slouken@2791
   415
    } else
slouken@2791
   416
        data->flipflags |= DSFLIP_ONSYNC;
slouken@2226
   417
slouken@5488
   418
    SDL_DFB_CHECKERR(winsurf->GetCapabilities(winsurf, &scaps));
slouken@5199
   419
slouken@5199
   420
#if 0
slouken@5199
   421
    if (scaps & DSCAPS_DOUBLE)
slouken@5199
   422
        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
slouken@5199
   423
    else if (scaps & DSCAPS_TRIPLE)
slouken@5199
   424
        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
slouken@5199
   425
    else
slouken@5199
   426
        renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
slouken@5199
   427
#endif
slouken@5199
   428
slouken@5199
   429
    DirectFB_SetSupportedPixelFormats(&renderer->info);
slouken@5199
   430
slouken@5199
   431
#if 0
slouken@5199
   432
    /* Set up a palette watch on the display palette */
slouken@5488
   433
    if (display-> palette) {
slouken@5199
   434
        SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
slouken@5199
   435
    }
slouken@5199
   436
#endif
slouken@2226
   437
slouken@2226
   438
    return renderer;
slouken@2226
   439
slouken@2226
   440
  error:
slouken@2226
   441
    SDL_DFB_FREE(renderer);
slouken@2226
   442
    SDL_DFB_FREE(data);
slouken@2226
   443
    return NULL;
slouken@2226
   444
}
slouken@2226
   445
slouken@5199
   446
static void
slouken@2737
   447
DirectFB_ActivateRenderer(SDL_Renderer * renderer)
slouken@2226
   448
{
slouken@2226
   449
    SDL_DFB_RENDERERDATA(renderer);
slouken@4568
   450
    SDL_Window *window = renderer->window;
slouken@2226
   451
    SDL_DFB_WINDOWDATA(window);
slouken@2226
   452
gabomdq@7678
   453
    if (renddata->size_changed /* || windata->wm_needs_redraw */) {
slouken@6989
   454
        renddata->size_changed = SDL_FALSE;
slouken@2737
   455
    }
slouken@2226
   456
}
slouken@2226
   457
slouken@2737
   458
slouken@2737
   459
static int
slouken@2721
   460
DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2721
   461
{
slouken@4568
   462
    SDL_Window *window = renderer->window;
slouken@5246
   463
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@2721
   464
    SDL_DFB_DEVICEDATA(display->device);
slouken@2721
   465
    DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
slouken@2721
   466
    DirectFB_TextureData *data = texture->driverdata;
slouken@2721
   467
    DFBDisplayLayerConfig layconf;
slouken@4636
   468
    DFBResult ret;
slouken@2721
   469
slouken@5199
   470
    if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
slouken@2721
   471
        && (!dispdata->vidIDinuse)
slouken@2721
   472
        && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
slouken@2737
   473
        layconf.flags =
slouken@2737
   474
            DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
slouken@2737
   475
            DLCONF_SURFACE_CAPS;
slouken@2721
   476
        layconf.width = texture->w;
slouken@2721
   477
        layconf.height = texture->h;
slouken@5199
   478
        layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format);
slouken@2737
   479
        layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
slouken@2721
   480
couriersud@3023
   481
        SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
couriersud@3023
   482
                                                       dispdata->vidID,
couriersud@3023
   483
                                                       &dispdata->vidlayer));
couriersud@3023
   484
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
   485
                         vidlayer->SetCooperativeLevel(dispdata->vidlayer,
couriersud@3023
   486
                                                       DLSCL_EXCLUSIVE));
slouken@2737
   487
slouken@2737
   488
        if (devdata->use_yuv_underlays) {
slouken@5199
   489
            ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
slouken@2737
   490
            if (ret != DFB_OK)
slouken@2737
   491
                SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
slouken@2737
   492
        }
couriersud@3023
   493
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
   494
                         vidlayer->SetConfiguration(dispdata->vidlayer,
couriersud@3023
   495
                                                    &layconf));
couriersud@3023
   496
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
   497
                         vidlayer->GetSurface(dispdata->vidlayer,
couriersud@3023
   498
                                              &data->surface));
slouken@2721
   499
        dispdata->vidIDinuse = 1;
slouken@2737
   500
        data->display = display;
slouken@2721
   501
        return 0;
slouken@2721
   502
    }
slouken@2721
   503
    return 1;
slouken@2721
   504
  error:
slouken@2737
   505
    if (dispdata->vidlayer) {
slouken@2721
   506
        SDL_DFB_RELEASE(data->surface);
couriersud@3023
   507
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
   508
                         vidlayer->SetCooperativeLevel(dispdata->vidlayer,
couriersud@3023
   509
                                                       DLSCL_ADMINISTRATIVE));
slouken@2737
   510
        SDL_DFB_RELEASE(dispdata->vidlayer);
slouken@2721
   511
    }
slouken@2721
   512
    return 1;
slouken@2721
   513
}
slouken@2721
   514
slouken@2721
   515
static int
slouken@2226
   516
DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2226
   517
{
slouken@4568
   518
    SDL_Window *window = renderer->window;
slouken@5246
   519
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@2226
   520
    SDL_DFB_DEVICEDATA(display->device);
slouken@2226
   521
    DirectFB_TextureData *data;
slouken@2226
   522
    DFBSurfaceDescription dsc;
slouken@3335
   523
    DFBSurfacePixelFormat pixelformat;
slouken@2226
   524
slouken@5199
   525
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   526
slouken@5199
   527
    SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
slouken@2226
   528
    texture->driverdata = data;
slouken@2226
   529
slouken@3335
   530
    /* find the right pixelformat */
slouken@5199
   531
    pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format);
slouken@3335
   532
    if (pixelformat == DSPF_UNKNOWN) {
slouken@3335
   533
        SDL_SetError("Unknown pixel format %d\n", data->format);
slouken@3335
   534
        goto error;
slouken@3335
   535
    }
slouken@3335
   536
slouken@2226
   537
    data->format = texture->format;
slouken@3335
   538
    data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
slouken@2226
   539
slouken@2721
   540
    if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
slouken@2226
   541
        /* fill surface description */
slouken@2226
   542
        dsc.flags =
slouken@2226
   543
            DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
slouken@2226
   544
        dsc.width = texture->w;
slouken@2226
   545
        dsc.height = texture->h;
slouken@5199
   546
        if(texture->format == SDL_PIXELFORMAT_YV12 ||
slouken@5199
   547
           texture->format == SDL_PIXELFORMAT_IYUV) {
slouken@5199
   548
           /* dfb has problems with odd sizes -make them even internally */
slouken@5199
   549
           dsc.width += (dsc.width % 2);
slouken@5199
   550
           dsc.height += (dsc.height % 2);
slouken@5199
   551
        }
slouken@2721
   552
        /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
slouken@2226
   553
         * No DSCAPS_SYSTEMONLY either - let dfb decide
slouken@2721
   554
         * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
slouken@2737
   555
         * Depends on other settings as well. Let dfb decide.
slouken@2226
   556
         */
slouken@2721
   557
        dsc.caps = DSCAPS_PREMULTIPLIED;
slouken@2737
   558
#if 0
slouken@2721
   559
        if (texture->access == SDL_TEXTUREACCESS_STREAMING)
slouken@2721
   560
            dsc.caps |= DSCAPS_SYSTEMONLY;
slouken@2721
   561
        else
slouken@2721
   562
            dsc.caps |= DSCAPS_VIDEOONLY;
slouken@2737
   563
#endif
slouken@2226
   564
slouken@3335
   565
        dsc.pixelformat = pixelformat;
slouken@2226
   566
        data->pixels = NULL;
slouken@2226
   567
slouken@2226
   568
        /* Create the surface */
couriersud@3023
   569
        SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
couriersud@3023
   570
                                                     &data->surface));
slouken@5199
   571
        if (SDL_ISPIXELFORMAT_INDEXED(data->format)
slouken@5199
   572
            && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
slouken@5199
   573
#if 1
slouken@5199
   574
            SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette));
slouken@5199
   575
#else
slouken@5199
   576
            /* DFB has issues with blitting LUT8 surfaces.
slouken@6989
   577
             * Creating a new palette does not help.
slouken@6989
   578
             */
slouken@6989
   579
            DFBPaletteDescription pal_desc;
slouken@7191
   580
            pal_desc.flags = DPDESC_SIZE; /* | DPDESC_ENTRIES */
slouken@6989
   581
            pal_desc.size = 256;
slouken@6989
   582
            SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette));
slouken@6989
   583
            SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette));
slouken@5199
   584
#endif
slouken@5199
   585
        }
slouken@5199
   586
slouken@2226
   587
    }
couriersud@3037
   588
#if (DFB_VERSION_ATLEAST(1,2,0))
slouken@2737
   589
    data->render_options = DSRO_NONE;
slouken@2737
   590
#endif
slouken@2737
   591
    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
slouken@3335
   592
        /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
slouken@3335
   593
        if(texture->format == SDL_PIXELFORMAT_YV12 ||
slouken@3335
   594
           texture->format == SDL_PIXELFORMAT_IYUV) {
slouken@5199
   595
            SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch  + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
slouken@3335
   596
        } else {
slouken@5199
   597
            SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch);
slouken@3335
   598
        }
slouken@2737
   599
    }
slouken@2737
   600
slouken@2226
   601
    return 0;
slouken@2226
   602
slouken@2226
   603
  error:
slouken@2226
   604
    SDL_DFB_RELEASE(data->palette);
slouken@2226
   605
    SDL_DFB_RELEASE(data->surface);
slouken@2226
   606
    SDL_DFB_FREE(texture->driverdata);
slouken@2226
   607
    return -1;
slouken@2226
   608
}
slouken@2226
   609
slouken@2226
   610
static int
couriersud@3023
   611
DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
couriersud@3023
   612
                            SDL_Texture * texture, void **pixels, int *pitch)
slouken@2226
   613
{
slouken@2737
   614
    DirectFB_TextureData *texturedata =
slouken@2737
   615
        (DirectFB_TextureData *) texture->driverdata;
slouken@2226
   616
slouken@2737
   617
    if (texturedata->display) {
slouken@2737
   618
        return -1;
slouken@2737
   619
    } else {
slouken@2737
   620
        *pixels = texturedata->pixels;
slouken@2737
   621
        *pitch = texturedata->pitch;
slouken@2737
   622
    }
slouken@2737
   623
    return 0;
slouken@2226
   624
}
slouken@2226
   625
slouken@2226
   626
static int
slouken@5199
   627
DirectFB_SetTexturePalette(SDL_Renderer * renderer,
slouken@5199
   628
                           SDL_Texture * texture,
slouken@5199
   629
                           const SDL_Color * colors, int firstcolor,
slouken@5199
   630
                           int ncolors)
slouken@5199
   631
{
slouken@5199
   632
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@5199
   633
    if (SDL_ISPIXELFORMAT_INDEXED(data->format)
slouken@5199
   634
        && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
slouken@5199
   635
        DFBColor entries[256];
slouken@5199
   636
        int i;
slouken@5199
   637
slouken@5199
   638
        if (ncolors > 256)
slouken@6989
   639
            ncolors = 256;
slouken@5199
   640
slouken@5199
   641
        for (i = 0; i < ncolors; ++i) {
slouken@5199
   642
            entries[i].r = colors[i].r;
slouken@5199
   643
            entries[i].g = colors[i].g;
slouken@5199
   644
            entries[i].b = colors[i].b;
slouken@5199
   645
            entries[i].a = 0xff;
slouken@5199
   646
        }
slouken@5199
   647
        SDL_DFB_CHECKERR(data->
slouken@5199
   648
                         palette->SetEntries(data->palette, entries, ncolors, firstcolor));
slouken@5199
   649
        return 0;
slouken@5199
   650
    } else {
icculus@7037
   651
        return SDL_SetError("YUV textures don't have a palette");
slouken@5199
   652
    }
slouken@5199
   653
  error:
slouken@5199
   654
    return -1;
slouken@5199
   655
}
slouken@5199
   656
slouken@5199
   657
static int
slouken@5199
   658
DirectFB_GetTexturePalette(SDL_Renderer * renderer,
slouken@5199
   659
                           SDL_Texture * texture, SDL_Color * colors,
slouken@5199
   660
                           int firstcolor, int ncolors)
slouken@5199
   661
{
slouken@5199
   662
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@5199
   663
slouken@5199
   664
    if (SDL_ISPIXELFORMAT_INDEXED(data->format)
slouken@5199
   665
        && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
slouken@5199
   666
        DFBColor entries[256];
slouken@5199
   667
        int i;
slouken@5199
   668
slouken@5199
   669
        SDL_DFB_CHECKERR(data->
slouken@5199
   670
                         palette->GetEntries(data->palette, entries, ncolors,
slouken@5199
   671
                                             firstcolor));
slouken@5199
   672
slouken@5199
   673
        for (i = 0; i < ncolors; ++i) {
slouken@5199
   674
            colors[i].r = entries[i].r;
slouken@5199
   675
            colors[i].g = entries[i].g;
slouken@5199
   676
            colors[i].b = entries[i].b;
slouken@7748
   677
            colors[i].a = SDL_ALPHA_OPAQUE;
slouken@5199
   678
        }
slouken@5199
   679
        return 0;
slouken@5199
   680
    } else {
icculus@7037
   681
        return SDL_SetError("YUV textures don't have a palette");
slouken@5199
   682
    }
slouken@5199
   683
  error:
slouken@5199
   684
    return -1;
slouken@5199
   685
}
slouken@5199
   686
slouken@5199
   687
static int
slouken@5199
   688
DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@5199
   689
{
slouken@5199
   690
    return 0;
slouken@5199
   691
}
slouken@5199
   692
slouken@5199
   693
static int
slouken@5199
   694
DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@5199
   695
{
slouken@5199
   696
    return 0;
slouken@5199
   697
}
slouken@5199
   698
slouken@5199
   699
static int
slouken@5199
   700
DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@5199
   701
{
slouken@5199
   702
    switch (texture->blendMode) {
slouken@5199
   703
    case SDL_BLENDMODE_NONE:
gabomdq@7678
   704
    /* case SDL_BLENDMODE_MASK: */
slouken@5199
   705
    case SDL_BLENDMODE_BLEND:
slouken@5199
   706
    case SDL_BLENDMODE_ADD:
slouken@5199
   707
    case SDL_BLENDMODE_MOD:
slouken@5199
   708
        return 0;
slouken@5199
   709
    default:
slouken@5199
   710
        texture->blendMode = SDL_BLENDMODE_NONE;
icculus@7037
   711
        return SDL_Unsupported();
slouken@5199
   712
    }
slouken@5199
   713
}
slouken@5199
   714
slouken@5199
   715
static int
slouken@5199
   716
DirectFB_SetDrawBlendMode(SDL_Renderer * renderer)
slouken@5199
   717
{
slouken@5199
   718
    switch (renderer->blendMode) {
slouken@5199
   719
    case SDL_BLENDMODE_NONE:
gabomdq@7678
   720
    /* case SDL_BLENDMODE_MASK: */
slouken@5199
   721
    case SDL_BLENDMODE_BLEND:
slouken@5199
   722
    case SDL_BLENDMODE_ADD:
slouken@5199
   723
    case SDL_BLENDMODE_MOD:
slouken@5199
   724
        return 0;
slouken@5199
   725
    default:
slouken@5199
   726
        renderer->blendMode = SDL_BLENDMODE_NONE;
icculus@7037
   727
        return SDL_Unsupported();
slouken@5199
   728
    }
slouken@5199
   729
}
slouken@5199
   730
slouken@5199
   731
#if 0
slouken@5199
   732
static int
slouken@2226
   733
DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2226
   734
{
couriersud@3037
   735
#if (DFB_VERSION_ATLEAST(1,2,0))
slouken@2737
   736
slouken@2737
   737
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@2737
   738
slouken@2226
   739
    switch (texture->scaleMode) {
slouken@4929
   740
    case SDL_SCALEMODE_NONE:
slouken@4929
   741
    case SDL_SCALEMODE_FAST:
slouken@2737
   742
        data->render_options = DSRO_NONE;
slouken@2737
   743
        break;
slouken@4929
   744
    case SDL_SCALEMODE_SLOW:
slouken@2737
   745
        data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
slouken@2737
   746
        break;
slouken@4929
   747
    case SDL_SCALEMODE_BEST:
slouken@2737
   748
        data->render_options =
slouken@2737
   749
            DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
slouken@2737
   750
        break;
slouken@2226
   751
    default:
slouken@2737
   752
        data->render_options = DSRO_NONE;
slouken@4929
   753
        texture->scaleMode = SDL_SCALEMODE_NONE;
icculus@7037
   754
        return SDL_Unsupported();
slouken@2226
   755
    }
slouken@2737
   756
#endif
slouken@2226
   757
    return 0;
slouken@2226
   758
}
slouken@5199
   759
#endif
slouken@2226
   760
slouken@2226
   761
static int
slouken@2226
   762
DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2226
   763
                       const SDL_Rect * rect, const void *pixels, int pitch)
slouken@2226
   764
{
slouken@2226
   765
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@2241
   766
    Uint8 *dpixels;
slouken@2244
   767
    int dpitch;
slouken@2241
   768
    Uint8 *src, *dst;
slouken@2241
   769
    int row;
slouken@2241
   770
    size_t length;
slouken@5199
   771
    int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
slouken@7191
   772
    /* FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes */
slouken@2226
   773
slouken@5199
   774
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   775
slouken@5199
   776
    if ((texture->format == SDL_PIXELFORMAT_YV12) ||
slouken@5199
   777
        (texture->format == SDL_PIXELFORMAT_IYUV)) {
slouken@5199
   778
        bpp = 1;
slouken@5199
   779
    }
slouken@6989
   780
slouken@2241
   781
    SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
slouken@2721
   782
                                         DSLF_WRITE | DSLF_READ,
slouken@2721
   783
                                         ((void **) &dpixels), &dpitch));
slouken@2241
   784
    src = (Uint8 *) pixels;
slouken@2930
   785
    dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp;
slouken@2930
   786
    length = rect->w * bpp;
slouken@2241
   787
    for (row = 0; row < rect->h; ++row) {
slouken@2241
   788
        SDL_memcpy(dst, src, length);
slouken@2241
   789
        src += pitch;
slouken@2241
   790
        dst += dpitch;
slouken@2241
   791
    }
slouken@3335
   792
    /* copy other planes for 3 plane formats */
slouken@5199
   793
    if ((texture->format == SDL_PIXELFORMAT_YV12) ||
slouken@5199
   794
        (texture->format == SDL_PIXELFORMAT_IYUV)) {
slouken@3335
   795
        src = (Uint8 *) pixels + texture->h * pitch;
slouken@3335
   796
        dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
slouken@5199
   797
        for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
slouken@3335
   798
            SDL_memcpy(dst, src, length / 2);
slouken@3335
   799
            src += pitch / 2;
slouken@3335
   800
            dst += dpitch / 2;
slouken@3335
   801
        }
slouken@3335
   802
        src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
slouken@3335
   803
        dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
slouken@5199
   804
        for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
slouken@3335
   805
            SDL_memcpy(dst, src, length / 2);
slouken@3335
   806
            src += pitch / 2;
slouken@3335
   807
            dst += dpitch / 2;
slouken@3335
   808
        }
slouken@3335
   809
    }
slouken@2244
   810
    SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
slouken@5199
   811
    data->isDirty = 0;
slouken@2241
   812
    return 0;
slouken@2244
   813
  error:
slouken@2244
   814
    return 1;
slouken@2226
   815
slouken@2226
   816
}
slouken@2226
   817
slouken@2226
   818
static int
slouken@2226
   819
DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@5199
   820
                     const SDL_Rect * rect, void **pixels, int *pitch)
slouken@2226
   821
{
slouken@2737
   822
    DirectFB_TextureData *texturedata =
slouken@2737
   823
        (DirectFB_TextureData *) texture->driverdata;
slouken@2226
   824
slouken@5199
   825
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   826
slouken@5199
   827
#if 0
slouken@2737
   828
    if (markDirty) {
slouken@2737
   829
        SDL_AddDirtyRect(&texturedata->dirty, rect);
slouken@2226
   830
    }
slouken@5199
   831
#endif
slouken@2226
   832
slouken@2737
   833
    if (texturedata->display) {
slouken@2737
   834
        void *fdata;
slouken@2737
   835
        int fpitch;
slouken@2226
   836
slouken@2737
   837
        SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
slouken@2737
   838
                                                    DSLF_WRITE | DSLF_READ,
slouken@2737
   839
                                                    &fdata, &fpitch));
slouken@2737
   840
        *pitch = fpitch;
slouken@2737
   841
        *pixels = fdata;
slouken@2737
   842
    } else {
slouken@2737
   843
        *pixels =
slouken@2737
   844
            (void *) ((Uint8 *) texturedata->pixels +
slouken@2737
   845
                      rect->y * texturedata->pitch +
slouken@5199
   846
                      rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)));
slouken@2737
   847
        *pitch = texturedata->pitch;
slouken@5199
   848
        texturedata->isDirty = 1;
slouken@2737
   849
    }
slouken@2226
   850
    return 0;
slouken@2737
   851
slouken@2226
   852
  error:
slouken@2226
   853
    return -1;
slouken@2226
   854
}
slouken@2226
   855
slouken@2226
   856
static void
slouken@2226
   857
DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2226
   858
{
slouken@2737
   859
    DirectFB_TextureData *texturedata =
slouken@2737
   860
        (DirectFB_TextureData *) texture->driverdata;
slouken@2226
   861
slouken@5199
   862
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   863
slouken@2737
   864
    if (texturedata->display) {
slouken@4636
   865
        SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
slouken@2737
   866
        texturedata->pixels = NULL;
slouken@2737
   867
    }
slouken@2226
   868
}
slouken@2226
   869
slouken@5199
   870
#if 0
slouken@2226
   871
static void
slouken@2226
   872
DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2226
   873
                      int numrects, const SDL_Rect * rects)
slouken@2226
   874
{
slouken@2737
   875
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@2737
   876
    int i;
slouken@2737
   877
slouken@2737
   878
    for (i = 0; i < numrects; ++i) {
slouken@2737
   879
        SDL_AddDirtyRect(&data->dirty, &rects[i]);
slouken@2737
   880
    }
slouken@2226
   881
}
slouken@5199
   882
#endif
slouken@2226
   883
slouken@6989
   884
static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@6989
   885
{
slouken@6989
   886
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   887
    DirectFB_TextureData *tex_data = NULL;
slouken@6989
   888
slouken@6989
   889
    DirectFB_ActivateRenderer(renderer);
slouken@6989
   890
    if (texture) {
slouken@6989
   891
        tex_data = (DirectFB_TextureData *) texture->driverdata;
slouken@6989
   892
        data->target = tex_data->surface;
slouken@6989
   893
    } else {
slouken@6989
   894
        data->target = get_dfb_surface(data->window);
slouken@6989
   895
    }
slouken@6989
   896
    data->lastBlendMode = 0;
slouken@6989
   897
    return 0;
slouken@6989
   898
}
slouken@6989
   899
slouken@6989
   900
slouken@2226
   901
static int
slouken@2884
   902
PrepareDraw(SDL_Renderer * renderer)
slouken@2884
   903
{
slouken@2884
   904
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   905
    IDirectFBSurface *destsurf = data->target;
slouken@3040
   906
slouken@2884
   907
    Uint8 r, g, b, a;
slouken@2884
   908
slouken@2884
   909
    r = renderer->r;
slouken@2884
   910
    g = renderer->g;
slouken@2884
   911
    b = renderer->b;
slouken@2884
   912
    a = renderer->a;
slouken@2884
   913
slouken@2884
   914
    SetBlendMode(data, renderer->blendMode, NULL);
slouken@3040
   915
    SDL_DFB_CHECKERR(destsurf->SetDrawingFlags(destsurf, data->drawFlags));
slouken@2884
   916
slouken@2884
   917
    switch (renderer->blendMode) {
slouken@2884
   918
    case SDL_BLENDMODE_NONE:
gabomdq@7678
   919
    /* case SDL_BLENDMODE_MASK: */
slouken@2884
   920
    case SDL_BLENDMODE_BLEND:
slouken@2884
   921
        break;
slouken@2884
   922
    case SDL_BLENDMODE_ADD:
slouken@5199
   923
    case SDL_BLENDMODE_MOD:
slouken@2884
   924
        r = ((int) r * (int) a) / 255;
slouken@2884
   925
        g = ((int) g * (int) a) / 255;
slouken@2884
   926
        b = ((int) b * (int) a) / 255;
slouken@2884
   927
        a = 255;
slouken@2884
   928
        break;
slouken@2884
   929
    }
slouken@2884
   930
couriersud@3038
   931
    SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, r, g, b, a));
slouken@2884
   932
    return 0;
slouken@2884
   933
  error:
slouken@2884
   934
    return -1;
slouken@2884
   935
}
slouken@2884
   936
couriersud@3640
   937
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
slouken@6986
   938
                                const SDL_FPoint * points, int count)
slouken@2901
   939
{
slouken@2901
   940
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   941
    IDirectFBSurface *destsurf = data->target;
slouken@6995
   942
    DFBRegion clip_region;
couriersud@3640
   943
    int i;
slouken@2901
   944
slouken@5199
   945
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   946
slouken@2901
   947
    PrepareDraw(renderer);
slouken@6995
   948
    destsurf->GetClip(destsurf, &clip_region);
slouken@6995
   949
    for (i=0; i < count; i++) {
slouken@6995
   950
        int x = points[i].x + clip_region.x1;
slouken@6995
   951
        int y = points[i].y + clip_region.y1;
slouken@6995
   952
        SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x, y, x, y));
slouken@6995
   953
    }
couriersud@3640
   954
    return 0;
couriersud@3640
   955
  error:
couriersud@3640
   956
    return -1;
couriersud@3640
   957
}
couriersud@3640
   958
couriersud@3640
   959
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
slouken@6986
   960
                               const SDL_FPoint * points, int count)
couriersud@3640
   961
{
couriersud@3640
   962
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   963
    IDirectFBSurface *destsurf = data->target;
slouken@6995
   964
    DFBRegion clip_region;
couriersud@3640
   965
    int i;
couriersud@3640
   966
slouken@5199
   967
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   968
couriersud@3640
   969
    PrepareDraw(renderer);
couriersud@3640
   970
    /* Use antialiasing when available */
couriersud@3640
   971
#if (DFB_VERSION_ATLEAST(1,2,0))
couriersud@3640
   972
    SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS));
couriersud@3640
   973
#endif
couriersud@3640
   974
slouken@6995
   975
    destsurf->GetClip(destsurf, &clip_region);
slouken@6995
   976
    for (i=0; i < count - 1; i++) {
slouken@6995
   977
        int x1 = points[i].x + clip_region.x1;
slouken@6995
   978
        int y1 = points[i].y + clip_region.y1;
slouken@6995
   979
        int x2 = points[i + 1].x + clip_region.x1;
slouken@6995
   980
        int y2 = points[i + 1].y + clip_region.y1;
slouken@6995
   981
        SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x1, y1, x2, y2));
slouken@6995
   982
    }
couriersud@3640
   983
slouken@2901
   984
    return 0;
slouken@2901
   985
  error:
slouken@2901
   986
    return -1;
slouken@2901
   987
}
slouken@2901
   988
slouken@2901
   989
static int
slouken@5199
   990
DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
slouken@5199
   991
{
slouken@5199
   992
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
   993
    IDirectFBSurface *destsurf = data->target;
slouken@6995
   994
    DFBRegion clip_region;
slouken@5199
   995
    int i;
slouken@5199
   996
slouken@5199
   997
    DirectFB_ActivateRenderer(renderer);
slouken@5199
   998
slouken@5199
   999
    PrepareDraw(renderer);
slouken@5199
  1000
slouken@6995
  1001
    destsurf->GetClip(destsurf, &clip_region);
slouken@6995
  1002
    for (i=0; i<count; i++) {
slouken@6995
  1003
        SDL_Rect dst = {rects[i]->x, rects[i]->y, rects[i]->w, rects[i]->h};
slouken@6995
  1004
        dst.x += clip_region.x1;
slouken@6995
  1005
        dst.y += clip_region.y1;
slouken@6995
  1006
        SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, dst.x, dst.y,
slouken@6995
  1007
                dst.w, dst.h));
slouken@6995
  1008
    }
slouken@5199
  1009
slouken@5199
  1010
    return 0;
slouken@5199
  1011
  error:
slouken@5199
  1012
    return -1;
slouken@5199
  1013
}
slouken@5199
  1014
slouken@5199
  1015
static int
slouken@6986
  1016
DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
slouken@2884
  1017
{
slouken@2884
  1018
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
  1019
    IDirectFBSurface *destsurf = data->target;
slouken@6995
  1020
    DFBRegion clip_region;
couriersud@3640
  1021
    int i;
slouken@2884
  1022
slouken@5199
  1023
    DirectFB_ActivateRenderer(renderer);
slouken@5199
  1024
slouken@2884
  1025
    PrepareDraw(renderer);
couriersud@3640
  1026
slouken@6995
  1027
    destsurf->GetClip(destsurf, &clip_region);
slouken@6995
  1028
    for (i=0; i<count; i++) {
slouken@7191
  1029
        SDL_Rect dst = {rects[i].x, rects[i].y, rects[i].w, rects[i].h};
slouken@6995
  1030
        dst.x += clip_region.x1;
slouken@6995
  1031
        dst.y += clip_region.y1;
slouken@6995
  1032
        SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, dst.x, dst.y,
slouken@6995
  1033
                dst.w, dst.h));
slouken@6995
  1034
    }
slouken@2226
  1035
slouken@2226
  1036
    return 0;
slouken@2226
  1037
  error:
slouken@2226
  1038
    return -1;
slouken@2226
  1039
}
slouken@2226
  1040
slouken@2226
  1041
static int
slouken@2226
  1042
DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@6986
  1043
                    const SDL_Rect * srcrect, const SDL_FRect * dstrect)
slouken@2226
  1044
{
slouken@2226
  1045
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
  1046
    IDirectFBSurface *destsurf = data->target;
slouken@2226
  1047
    DirectFB_TextureData *texturedata =
slouken@2226
  1048
        (DirectFB_TextureData *) texture->driverdata;
slouken@5199
  1049
    Uint8 alpha, r, g, b;
slouken@6995
  1050
    DFBRegion clip_region;
slouken@6986
  1051
    DFBRectangle sr, dr;
slouken@5199
  1052
slouken@5199
  1053
    DirectFB_ActivateRenderer(renderer);
slouken@2226
  1054
slouken@6986
  1055
    SDLtoDFBRect(srcrect, &sr);
slouken@6986
  1056
    SDLtoDFBRect_Float(dstrect, &dr);
slouken@6986
  1057
slouken@6995
  1058
    destsurf->GetClip(destsurf, &clip_region);
slouken@6995
  1059
    dr.x += clip_region.x1;
slouken@6995
  1060
    dr.y += clip_region.y1;
slouken@6995
  1061
slouken@2737
  1062
    if (texturedata->display) {
slouken@2226
  1063
        int px, py;
slouken@4568
  1064
        SDL_Window *window = renderer->window;
slouken@6989
  1065
        IDirectFBWindow *dfbwin = get_dfb_window(window);
slouken@2737
  1066
        SDL_DFB_WINDOWDATA(window);
slouken@2737
  1067
        SDL_VideoDisplay *display = texturedata->display;
slouken@2226
  1068
        DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
slouken@2226
  1069
couriersud@3023
  1070
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
  1071
                         vidlayer->SetSourceRectangle(dispdata->vidlayer,
slouken@6986
  1072
                                                      sr.x, sr.y, sr.w, sr.h));
slouken@5488
  1073
        dfbwin->GetPosition(dfbwin, &px, &py);
couriersud@3023
  1074
        px += windata->client.x;
couriersud@3023
  1075
        py += windata->client.y;
couriersud@3023
  1076
        SDL_DFB_CHECKERR(dispdata->
couriersud@3023
  1077
                         vidlayer->SetScreenRectangle(dispdata->vidlayer,
slouken@6986
  1078
                                                      px + dr.x,
slouken@6986
  1079
                                                      py + dr.y,
slouken@6986
  1080
                                                      dr.w,
slouken@6986
  1081
                                                      dr.h));
slouken@2226
  1082
    } else {
slouken@2226
  1083
        DFBSurfaceBlittingFlags flags = 0;
slouken@2226
  1084
slouken@5199
  1085
#if 0
slouken@2737
  1086
        if (texturedata->dirty.list) {
slouken@2737
  1087
            SDL_DirtyRect *dirty;
slouken@2737
  1088
            void *pixels;
slouken@5199
  1089
            int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
slouken@2737
  1090
            int pitch = texturedata->pitch;
slouken@2226
  1091
slouken@2737
  1092
            for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
slouken@2737
  1093
                SDL_Rect *rect = &dirty->rect;
slouken@2737
  1094
                pixels =
slouken@2737
  1095
                    (void *) ((Uint8 *) texturedata->pixels +
slouken@2737
  1096
                              rect->y * pitch + rect->x * bpp);
slouken@2737
  1097
                DirectFB_UpdateTexture(renderer, texture, rect,
slouken@5199
  1098
                                       pixels,
slouken@2737
  1099
                                       texturedata->pitch);
slouken@2737
  1100
            }
slouken@2737
  1101
            SDL_ClearDirtyRects(&texturedata->dirty);
slouken@2737
  1102
        }
slouken@5199
  1103
#endif
slouken@5199
  1104
        if (texturedata->isDirty)
slouken@5199
  1105
        {
slouken@5199
  1106
            SDL_Rect rect;
slouken@5199
  1107
slouken@5199
  1108
            rect.x = 0;
slouken@5199
  1109
            rect.y = 0;
slouken@5199
  1110
            rect.w = texture->w;
slouken@5199
  1111
            rect.h = texture->h;
slouken@5199
  1112
slouken@5199
  1113
            DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
slouken@5199
  1114
        }
slouken@2884
  1115
slouken@5199
  1116
        alpha = r = g = b = 0xff;
slouken@6989
  1117
        if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){
slouken@6989
  1118
            alpha = texture->a;
slouken@6989
  1119
            flags |= DSBLIT_BLEND_COLORALPHA;
slouken@6989
  1120
        }
slouken@5199
  1121
slouken@5199
  1122
        if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
slouken@5199
  1123
            r = texture->r;
slouken@5199
  1124
            g = texture->g;
slouken@5199
  1125
            b = texture->b;
slouken@5199
  1126
            flags |= DSBLIT_COLORIZE;
slouken@5199
  1127
        }
slouken@3040
  1128
        SDL_DFB_CHECKERR(destsurf->
slouken@5199
  1129
                         SetColor(destsurf, r, g, b, alpha));
slouken@2884
  1130
slouken@7191
  1131
        /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
slouken@2884
  1132
slouken@2884
  1133
        SetBlendMode(data, texture->blendMode, texturedata);
slouken@2884
  1134
couriersud@3038
  1135
        SDL_DFB_CHECKERR(destsurf->SetBlittingFlags(destsurf,
slouken@3040
  1136
                                                    data->blitFlags | flags));
slouken@2884
  1137
couriersud@3037
  1138
#if (DFB_VERSION_ATLEAST(1,2,0))
couriersud@3038
  1139
        SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf,
slouken@3040
  1140
                                                    texturedata->
slouken@3040
  1141
                                                    render_options));
slouken@2737
  1142
#endif
slouken@2737
  1143
slouken@2226
  1144
        if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
couriersud@3038
  1145
            SDL_DFB_CHECKERR(destsurf->Blit(destsurf,
slouken@3040
  1146
                                            texturedata->surface,
slouken@3040
  1147
                                            &sr, dr.x, dr.y));
slouken@2226
  1148
        } else {
couriersud@3038
  1149
            SDL_DFB_CHECKERR(destsurf->StretchBlit(destsurf,
slouken@3040
  1150
                                                   texturedata->surface,
slouken@3040
  1151
                                                   &sr, &dr));
slouken@2226
  1152
        }
slouken@2226
  1153
    }
slouken@2226
  1154
    return 0;
slouken@2226
  1155
  error:
slouken@2226
  1156
    return -1;
slouken@2226
  1157
}
slouken@2226
  1158
slouken@2226
  1159
static void
slouken@2226
  1160
DirectFB_RenderPresent(SDL_Renderer * renderer)
slouken@2226
  1161
{
slouken@2226
  1162
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@4568
  1163
    SDL_Window *window = renderer->window;
couriersud@3023
  1164
    SDL_DFB_WINDOWDATA(window);
slouken@5199
  1165
    SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL);
slouken@2226
  1166
slouken@5199
  1167
    DirectFB_ActivateRenderer(renderer);
slouken@2226
  1168
slouken@5199
  1169
    if (shape_data && shape_data->surface) {
slouken@5199
  1170
        /* saturate the window surface alpha channel */
slouken@5199
  1171
        SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
slouken@5199
  1172
        SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
slouken@5199
  1173
        SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
slouken@5199
  1174
        SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
slouken@5199
  1175
        SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
slouken@5199
  1176
slouken@5199
  1177
        /* blit the mask */
slouken@5199
  1178
        SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
slouken@5199
  1179
        SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
slouken@5199
  1180
        SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
slouken@5199
  1181
#if (DFB_VERSION_ATLEAST(1,2,0))
slouken@5199
  1182
        SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
slouken@5199
  1183
#endif
slouken@5199
  1184
        SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0));
slouken@5199
  1185
    }
slouken@2226
  1186
slouken@2226
  1187
    /* Send the data to the display */
couriersud@3023
  1188
    SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
couriersud@3023
  1189
                                                data->flipflags));
slouken@2226
  1190
}
slouken@2226
  1191
slouken@2226
  1192
static void
slouken@2226
  1193
DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2226
  1194
{
slouken@2226
  1195
    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
slouken@2226
  1196
slouken@5199
  1197
    DirectFB_ActivateRenderer(renderer);
slouken@5199
  1198
slouken@2226
  1199
    if (!data) {
slouken@2226
  1200
        return;
slouken@2226
  1201
    }
slouken@2226
  1202
    SDL_DFB_RELEASE(data->palette);
slouken@2226
  1203
    SDL_DFB_RELEASE(data->surface);
slouken@2721
  1204
    if (data->display) {
slouken@2737
  1205
        DFB_DisplayData *dispdata =
slouken@2737
  1206
            (DFB_DisplayData *) data->display->driverdata;
slouken@2737
  1207
        dispdata->vidIDinuse = 0;
slouken@4636
  1208
        /* FIXME: Shouldn't we reset the cooperative level */
slouken@4636
  1209
        SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
slouken@4636
  1210
                                                DLSCL_ADMINISTRATIVE));
slouken@2737
  1211
        SDL_DFB_RELEASE(dispdata->vidlayer);
slouken@2721
  1212
    }
slouken@2737
  1213
    SDL_DFB_FREE(data->pixels);
slouken@2226
  1214
    SDL_free(data);
slouken@2226
  1215
    texture->driverdata = NULL;
slouken@2226
  1216
}
slouken@2226
  1217
slouken@2226
  1218
static void
slouken@2226
  1219
DirectFB_DestroyRenderer(SDL_Renderer * renderer)
slouken@2226
  1220
{
slouken@2226
  1221
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@5488
  1222
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window);
slouken@5199
  1223
#if 0
slouken@5199
  1224
    if (display->palette) {
slouken@5199
  1225
        SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
slouken@5199
  1226
    }
slouken@5199
  1227
#endif
slouken@3040
  1228
slouken@7719
  1229
    SDL_free(data);
slouken@2226
  1230
    SDL_free(renderer);
slouken@2226
  1231
}
slouken@2226
  1232
slouken@5199
  1233
static int
slouken@5488
  1234
DirectFB_UpdateViewport(SDL_Renderer * renderer)
slouken@5488
  1235
{
slouken@6989
  1236
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
  1237
    IDirectFBSurface *winsurf = data->target;
slouken@6989
  1238
    DFBRegion dreg;
slouken@5488
  1239
slouken@6989
  1240
    dreg.x1 = renderer->viewport.x;
slouken@6989
  1241
    dreg.y1 = renderer->viewport.y;
slouken@6989
  1242
    dreg.x2 = dreg.x1 + renderer->viewport.w - 1;
slouken@6989
  1243
    dreg.y2 = dreg.y1 + renderer->viewport.h - 1;
slouken@5488
  1244
slouken@6989
  1245
    winsurf->SetClip(winsurf, &dreg);
slouken@5488
  1246
    return 0;
slouken@5488
  1247
}
slouken@5488
  1248
slouken@5488
  1249
static int
slouken@7141
  1250
DirectFB_UpdateClipRect(SDL_Renderer * renderer)
slouken@7141
  1251
{
slouken@7141
  1252
    const SDL_Rect *rect = &renderer->clip_rect;
slouken@7141
  1253
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@7141
  1254
    IDirectFBSurface *destsurf = get_dfb_surface(data->window);
slouken@7141
  1255
    DFBRegion region;
slouken@7141
  1256
slouken@7141
  1257
    if (!SDL_RectEmpty(rect)) {
slouken@7141
  1258
        region.x1 = rect->x;
slouken@7141
  1259
        region.x2 = rect->x + rect->w;
slouken@7141
  1260
        region.y1 = rect->y;
slouken@7141
  1261
        region.y2 = rect->y + rect->h;
slouken@7141
  1262
        SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, &region));
slouken@7141
  1263
    } else {
slouken@7141
  1264
        SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, NULL));
slouken@7141
  1265
    }
slouken@7141
  1266
    return 0;
slouken@7141
  1267
  error:
slouken@7141
  1268
    return -1;
slouken@7141
  1269
}
slouken@7141
  1270
slouken@7141
  1271
static int
slouken@5199
  1272
DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@5199
  1273
                     Uint32 format, void * pixels, int pitch)
slouken@5199
  1274
{
slouken@5199
  1275
    Uint32 sdl_format;
slouken@6989
  1276
    void * laypixels;
slouken@6989
  1277
    int laypitch;
slouken@6989
  1278
    DFBSurfacePixelFormat dfb_format;
slouken@6989
  1279
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
slouken@6989
  1280
    IDirectFBSurface *winsurf = data->target;
slouken@5199
  1281
slouken@5199
  1282
    DirectFB_ActivateRenderer(renderer);
slouken@5199
  1283
slouken@5488
  1284
    winsurf->GetPixelFormat(winsurf, &dfb_format);
slouken@5199
  1285
    sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
slouken@5488
  1286
    winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch);
slouken@6989
  1287
slouken@5199
  1288
    laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
slouken@5199
  1289
    SDL_ConvertPixels(rect->w, rect->h,
slouken@5199
  1290
                      sdl_format, laypixels, laypitch,
slouken@5199
  1291
                      format, pixels, pitch);
slouken@5199
  1292
slouken@5488
  1293
    winsurf->Unlock(winsurf);
slouken@6989
  1294
slouken@5199
  1295
    return 0;
slouken@5199
  1296
}
slouken@5199
  1297
slouken@5488
  1298
#if 0
slouken@5199
  1299
static int
slouken@5199
  1300
DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@5199
  1301
                      Uint32 format, const void * pixels, int pitch)
slouken@5199
  1302
{
slouken@5199
  1303
    SDL_Window *window = renderer->window;
slouken@5199
  1304
    SDL_DFB_WINDOWDATA(window);
slouken@5199
  1305
    Uint32 sdl_format;
slouken@6989
  1306
    void * laypixels;
slouken@6989
  1307
    int laypitch;
slouken@6989
  1308
    DFBSurfacePixelFormat dfb_format;
slouken@5199
  1309
slouken@5199
  1310
    SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
slouken@5199
  1311
    sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
slouken@5199
  1312
slouken@5199
  1313
    SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch));
slouken@6989
  1314
slouken@5199
  1315
    laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
slouken@5199
  1316
    SDL_ConvertPixels(rect->w, rect->h,
slouken@5199
  1317
                      format, pixels, pitch,
slouken@5199
  1318
                      sdl_format, laypixels, laypitch);
slouken@5199
  1319
slouken@5199
  1320
    SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
slouken@5199
  1321
slouken@5199
  1322
    return 0;
slouken@5199
  1323
}
slouken@5488
  1324
#endif
slouken@5199
  1325
slouken@6044
  1326
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
slouken@6044
  1327
slouken@2226
  1328
/* vi: set ts=4 sw=4 expandtab: */