src/video/vivante/SDL_vivantevideo.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 03 Jan 2018 10:03:25 -0800
changeset 11811 5d94cb6b24d3
parent 11530 14c4783c4143
child 12503 806492103856
permissions -rw-r--r--
Updated copyright for 2018
slouken@9164
     1
/*
slouken@9164
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
slouken@9164
     4
slouken@9164
     5
  This software is provided 'as-is', without any express or implied
slouken@9164
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@9164
     7
  arising from the use of this software.
slouken@9164
     8
slouken@9164
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@9164
    10
  including commercial applications, and to alter it and redistribute it
slouken@9164
    11
  freely, subject to the following restrictions:
slouken@9164
    12
slouken@9164
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@9164
    14
     claim that you wrote the original software. If you use this software
slouken@9164
    15
     in a product, an acknowledgment in the product documentation would be
slouken@9164
    16
     appreciated but is not required.
slouken@9164
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@9164
    18
     misrepresented as being the original software.
slouken@9164
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@9164
    20
*/
slouken@9164
    21
#include "../../SDL_internal.h"
slouken@9164
    22
slouken@9164
    23
#if SDL_VIDEO_DRIVER_VIVANTE
slouken@9164
    24
slouken@9164
    25
/* SDL internals */
slouken@9164
    26
#include "../SDL_sysvideo.h"
slouken@9164
    27
#include "SDL_version.h"
slouken@9164
    28
#include "SDL_syswm.h"
slouken@9164
    29
#include "SDL_loadso.h"
slouken@9164
    30
#include "SDL_events.h"
slouken@9164
    31
#include "../../events/SDL_events_c.h"
slouken@9164
    32
slouken@9164
    33
#ifdef SDL_INPUT_LINUXEV
slouken@9164
    34
#include "../../core/linux/SDL_evdev.h"
slouken@9164
    35
#endif
slouken@9164
    36
slouken@9164
    37
#include "SDL_vivantevideo.h"
slouken@9164
    38
#include "SDL_vivanteplatform.h"
slouken@9164
    39
#include "SDL_vivanteopengles.h"
slouken@9164
    40
slouken@9164
    41
slouken@9164
    42
static int
slouken@9164
    43
VIVANTE_Available(void)
slouken@9164
    44
{
slouken@9164
    45
    return 1;
slouken@9164
    46
}
slouken@9164
    47
slouken@9164
    48
static void
slouken@9164
    49
VIVANTE_Destroy(SDL_VideoDevice * device)
slouken@9164
    50
{
slouken@9164
    51
    if (device->driverdata != NULL) {
slouken@9164
    52
        SDL_free(device->driverdata);
slouken@9164
    53
        device->driverdata = NULL;
slouken@9164
    54
    }
slouken@9164
    55
}
slouken@9164
    56
slouken@9164
    57
static SDL_VideoDevice *
slouken@9164
    58
VIVANTE_Create()
slouken@9164
    59
{
slouken@9164
    60
    SDL_VideoDevice *device;
slouken@9164
    61
    SDL_VideoData *data;
slouken@9164
    62
slouken@9164
    63
    /* Initialize SDL_VideoDevice structure */
slouken@9164
    64
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
slouken@9164
    65
    if (device == NULL) {
slouken@9164
    66
        SDL_OutOfMemory();
slouken@9164
    67
        return NULL;
slouken@9164
    68
    }
slouken@9164
    69
slouken@9164
    70
    /* Initialize internal data */
slouken@9164
    71
    data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
slouken@9164
    72
    if (data == NULL) {
slouken@9164
    73
        SDL_OutOfMemory();
slouken@9164
    74
        SDL_free(device);
slouken@9164
    75
        return NULL;
slouken@9164
    76
    }
slouken@9164
    77
slouken@9164
    78
    device->driverdata = data;
slouken@9164
    79
philipp@10202
    80
    /* Setup amount of available displays */
slouken@9164
    81
    device->num_displays = 0;
slouken@9164
    82
slouken@9164
    83
    /* Set device free function */
slouken@9164
    84
    device->free = VIVANTE_Destroy;
slouken@9164
    85
slouken@9164
    86
    /* Setup all functions which we can handle */
slouken@9164
    87
    device->VideoInit = VIVANTE_VideoInit;
slouken@9164
    88
    device->VideoQuit = VIVANTE_VideoQuit;
slouken@9164
    89
    device->GetDisplayModes = VIVANTE_GetDisplayModes;
slouken@9164
    90
    device->SetDisplayMode = VIVANTE_SetDisplayMode;
slouken@11383
    91
    device->CreateSDLWindow = VIVANTE_CreateWindow;
slouken@9164
    92
    device->SetWindowTitle = VIVANTE_SetWindowTitle;
slouken@9164
    93
    device->SetWindowPosition = VIVANTE_SetWindowPosition;
slouken@9164
    94
    device->SetWindowSize = VIVANTE_SetWindowSize;
slouken@9164
    95
    device->ShowWindow = VIVANTE_ShowWindow;
slouken@9164
    96
    device->HideWindow = VIVANTE_HideWindow;
slouken@9164
    97
    device->DestroyWindow = VIVANTE_DestroyWindow;
slouken@9164
    98
    device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo;
slouken@9164
    99
slouken@11530
   100
#if SDL_VIDEO_OPENGL_EGL
slouken@9164
   101
    device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary;
slouken@9164
   102
    device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress;
slouken@9164
   103
    device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary;
slouken@9164
   104
    device->GL_CreateContext = VIVANTE_GLES_CreateContext;
slouken@9164
   105
    device->GL_MakeCurrent = VIVANTE_GLES_MakeCurrent;
slouken@9164
   106
    device->GL_SetSwapInterval = VIVANTE_GLES_SetSwapInterval;
slouken@9164
   107
    device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval;
slouken@9164
   108
    device->GL_SwapWindow = VIVANTE_GLES_SwapWindow;
slouken@9164
   109
    device->GL_DeleteContext = VIVANTE_GLES_DeleteContext;
slouken@11530
   110
#endif
slouken@9164
   111
slouken@9164
   112
    device->PumpEvents = VIVANTE_PumpEvents;
slouken@9164
   113
slouken@9164
   114
    return device;
slouken@9164
   115
}
slouken@9164
   116
slouken@9164
   117
VideoBootStrap VIVANTE_bootstrap = {
slouken@9164
   118
    "vivante",
slouken@9164
   119
    "Vivante EGL Video Driver",
slouken@9164
   120
    VIVANTE_Available,
slouken@9164
   121
    VIVANTE_Create
slouken@9164
   122
};
slouken@9164
   123
slouken@9164
   124
/*****************************************************************************/
slouken@9164
   125
/* SDL Video and Display initialization/handling functions                   */
slouken@9164
   126
/*****************************************************************************/
slouken@9164
   127
slouken@9164
   128
static int
slouken@9164
   129
VIVANTE_AddVideoDisplays(_THIS)
slouken@9164
   130
{
slouken@9164
   131
    SDL_VideoData *videodata = _this->driverdata;
slouken@9164
   132
    SDL_VideoDisplay display;
slouken@9164
   133
    SDL_DisplayMode current_mode;
slouken@9164
   134
    SDL_DisplayData *data;
slouken@9164
   135
    int pitch = 0, bpp = 0;
slouken@9164
   136
    unsigned long pixels = 0;
slouken@9164
   137
slouken@9164
   138
    data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
slouken@9164
   139
    if (data == NULL) {
slouken@9164
   140
        return SDL_OutOfMemory();
slouken@9164
   141
    }
slouken@9164
   142
slouken@9164
   143
    SDL_zero(current_mode);
slouken@9164
   144
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   145
    data->native_display = vdkGetDisplay(videodata->vdk_private);
slouken@9164
   146
slouken@9164
   147
    vdkGetDisplayInfo(data->native_display, &current_mode.w, &current_mode.h, &pixels, &pitch, &bpp);
slouken@9164
   148
#else
slouken@9164
   149
    data->native_display = videodata->fbGetDisplayByIndex(0);
slouken@9164
   150
slouken@9164
   151
    videodata->fbGetDisplayInfo(data->native_display, &current_mode.w, &current_mode.h, &pixels, &pitch, &bpp);
slouken@9164
   152
#endif /* SDL_VIDEO_DRIVER_VIVANTE_VDK */
slouken@9164
   153
slouken@9164
   154
    switch (bpp)
slouken@9164
   155
    {
slouken@9164
   156
    default: /* Is another format used? */
slouken@11530
   157
    case 32:
slouken@11530
   158
        current_mode.format = SDL_PIXELFORMAT_ARGB8888;
slouken@11530
   159
        break;
slouken@9164
   160
    case 16:
slouken@9164
   161
        current_mode.format = SDL_PIXELFORMAT_RGB565;
slouken@9164
   162
        break;
slouken@9164
   163
    }
slouken@9164
   164
    /* FIXME: How do we query refresh rate? */
slouken@9164
   165
    current_mode.refresh_rate = 60;
slouken@9164
   166
slouken@9164
   167
    SDL_zero(display);
slouken@11530
   168
    display.name = VIVANTE_GetDisplayName(_this);
slouken@9164
   169
    display.desktop_mode = current_mode;
slouken@9164
   170
    display.current_mode = current_mode;
slouken@9164
   171
    display.driverdata = data;
slouken@9164
   172
    SDL_AddVideoDisplay(&display);
slouken@9164
   173
    return 0;
slouken@9164
   174
}
slouken@9164
   175
slouken@9164
   176
int
slouken@9164
   177
VIVANTE_VideoInit(_THIS)
slouken@9164
   178
{
slouken@9164
   179
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
slouken@9164
   180
slouken@9164
   181
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   182
    videodata->vdk_private = vdkInitialize();
slouken@9164
   183
    if (!videodata->vdk_private) {
slouken@9164
   184
        return SDL_SetError("vdkInitialize() failed");
slouken@9164
   185
    }
slouken@9164
   186
#else
slouken@9164
   187
    videodata->egl_handle = SDL_LoadObject("libEGL.so.1");
slouken@9164
   188
    if (!videodata->egl_handle) {
slouken@9164
   189
        videodata->egl_handle = SDL_LoadObject("libEGL.so");
slouken@9164
   190
        if (!videodata->egl_handle) {
slouken@9164
   191
            return -1;
slouken@9164
   192
        }
slouken@9164
   193
    }
slouken@9164
   194
#define LOAD_FUNC(NAME) \
slouken@9164
   195
    videodata->NAME = SDL_LoadFunction(videodata->egl_handle, #NAME); \
slouken@9164
   196
    if (!videodata->NAME) return -1;
slouken@9164
   197
slouken@9164
   198
    LOAD_FUNC(fbGetDisplay);
slouken@9164
   199
    LOAD_FUNC(fbGetDisplayByIndex);
slouken@9164
   200
    LOAD_FUNC(fbGetDisplayGeometry);
slouken@9164
   201
    LOAD_FUNC(fbGetDisplayInfo);
slouken@9164
   202
    LOAD_FUNC(fbDestroyDisplay);
slouken@9164
   203
    LOAD_FUNC(fbCreateWindow);
slouken@9164
   204
    LOAD_FUNC(fbGetWindowGeometry);
slouken@9164
   205
    LOAD_FUNC(fbGetWindowInfo);
slouken@9164
   206
    LOAD_FUNC(fbDestroyWindow);
slouken@9164
   207
#endif
slouken@9164
   208
slouken@9164
   209
    if (VIVANTE_SetupPlatform(_this) < 0) {
slouken@9164
   210
        return -1;
slouken@9164
   211
    }
slouken@9164
   212
slouken@9164
   213
    if (VIVANTE_AddVideoDisplays(_this) < 0) {
slouken@9164
   214
        return -1;
slouken@9164
   215
    }
slouken@9164
   216
slouken@11530
   217
    VIVANTE_UpdateDisplayScale(_this);
slouken@11530
   218
slouken@9164
   219
#ifdef SDL_INPUT_LINUXEV
slouken@9164
   220
    if (SDL_EVDEV_Init() < 0) {
slouken@9164
   221
        return -1;
slouken@9164
   222
    }
slouken@9164
   223
#endif
slouken@9164
   224
slouken@9164
   225
    return 0;
slouken@9164
   226
}
slouken@9164
   227
slouken@9164
   228
void
slouken@9164
   229
VIVANTE_VideoQuit(_THIS)
slouken@9164
   230
{
slouken@9164
   231
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
slouken@9164
   232
slouken@9164
   233
#ifdef SDL_INPUT_LINUXEV
slouken@9164
   234
    SDL_EVDEV_Quit();
slouken@9164
   235
#endif
slouken@9164
   236
slouken@9169
   237
    VIVANTE_CleanupPlatform(_this);
slouken@9169
   238
slouken@9164
   239
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   240
    if (videodata->vdk_private) {
slouken@9164
   241
        vdkExit(videodata->vdk_private);
slouken@9164
   242
        videodata->vdk_private = NULL;
slouken@9164
   243
    }
slouken@9164
   244
#else
slouken@9164
   245
    if (videodata->egl_handle) {
slouken@9164
   246
        SDL_UnloadObject(videodata->egl_handle);
slouken@9164
   247
        videodata->egl_handle = NULL;
slouken@9164
   248
    }
slouken@9164
   249
#endif
slouken@9164
   250
}
slouken@9164
   251
slouken@9164
   252
void
slouken@9164
   253
VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
slouken@9164
   254
{
slouken@9164
   255
    /* Only one display mode available, the current one */
slouken@9164
   256
    SDL_AddDisplayMode(display, &display->current_mode);
slouken@9164
   257
}
slouken@9164
   258
slouken@9164
   259
int
slouken@9164
   260
VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@9164
   261
{
slouken@9164
   262
    return 0;
slouken@9164
   263
}
slouken@9164
   264
slouken@9164
   265
int
slouken@9164
   266
VIVANTE_CreateWindow(_THIS, SDL_Window * window)
slouken@9164
   267
{
slouken@9164
   268
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
slouken@9164
   269
    SDL_DisplayData *displaydata;
slouken@9164
   270
    SDL_WindowData *data;
slouken@9164
   271
slouken@9164
   272
    displaydata = SDL_GetDisplayDriverData(0);
slouken@9164
   273
slouken@9164
   274
    /* Allocate window internal data */
slouken@9164
   275
    data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
slouken@9164
   276
    if (data == NULL) {
slouken@9164
   277
        return SDL_OutOfMemory();
slouken@9164
   278
    }
slouken@9164
   279
slouken@9164
   280
    /* Setup driver data for this window */
slouken@9164
   281
    window->driverdata = data;
slouken@9164
   282
slouken@9164
   283
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   284
    data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
slouken@9164
   285
#else
slouken@9164
   286
    data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
slouken@9164
   287
#endif
slouken@9164
   288
    if (!data->native_window) {
slouken@9164
   289
        return SDL_SetError("VIVANTE: Can't create native window");
slouken@9164
   290
    }
slouken@9164
   291
slouken@11530
   292
#if SDL_VIDEO_OPENGL_EGL
slouken@9164
   293
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@9164
   294
        data->egl_surface = SDL_EGL_CreateSurface(_this, data->native_window);
slouken@9164
   295
        if (data->egl_surface == EGL_NO_SURFACE) {
slouken@9164
   296
            return SDL_SetError("VIVANTE: Can't create EGL surface");
slouken@9164
   297
        }
slouken@9164
   298
    } else {
slouken@9164
   299
        data->egl_surface = EGL_NO_SURFACE;
slouken@9164
   300
    }
slouken@11530
   301
#endif
slouken@9164
   302
slouken@9164
   303
    /* Window has been successfully created */
slouken@9164
   304
    return 0;
slouken@9164
   305
}
slouken@9164
   306
slouken@9164
   307
void
slouken@9164
   308
VIVANTE_DestroyWindow(_THIS, SDL_Window * window)
slouken@9164
   309
{
slouken@9164
   310
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
slouken@9164
   311
    SDL_WindowData *data;
slouken@9164
   312
slouken@9164
   313
    data = window->driverdata;
slouken@9164
   314
    if (data) {
slouken@11530
   315
#if SDL_VIDEO_OPENGL_EGL
slouken@9164
   316
        if (data->egl_surface != EGL_NO_SURFACE) {
slouken@9164
   317
            SDL_EGL_DestroySurface(_this, data->egl_surface);
slouken@9164
   318
        }
slouken@11530
   319
#endif
slouken@9164
   320
slouken@9164
   321
        if (data->native_window) {
slouken@9164
   322
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   323
            vdkDestroyWindow(data->native_window);
slouken@9164
   324
#else
slouken@9164
   325
            videodata->fbDestroyWindow(data->native_window);
slouken@9164
   326
#endif
slouken@9164
   327
        }
slouken@9164
   328
slouken@9164
   329
        SDL_free(data);
slouken@9164
   330
    }
slouken@9164
   331
    window->driverdata = NULL;
slouken@9164
   332
}
slouken@9164
   333
slouken@9164
   334
void
slouken@9164
   335
VIVANTE_SetWindowTitle(_THIS, SDL_Window * window)
slouken@9164
   336
{
slouken@9164
   337
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   338
    SDL_WindowData *data = window->driverdata;
slouken@9164
   339
    vdkSetWindowTitle(data->native_window, window->title);
slouken@9164
   340
#endif
slouken@9164
   341
}
slouken@9164
   342
slouken@9164
   343
void
slouken@9164
   344
VIVANTE_SetWindowPosition(_THIS, SDL_Window * window)
slouken@9164
   345
{
slouken@9164
   346
    /* FIXME */
slouken@9164
   347
}
slouken@9164
   348
slouken@9164
   349
void
slouken@9164
   350
VIVANTE_SetWindowSize(_THIS, SDL_Window * window)
slouken@9164
   351
{
slouken@9164
   352
    /* FIXME */
slouken@9164
   353
}
slouken@9164
   354
slouken@9164
   355
void
slouken@9164
   356
VIVANTE_ShowWindow(_THIS, SDL_Window * window)
slouken@9164
   357
{
slouken@9164
   358
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   359
    SDL_WindowData *data = window->driverdata;
slouken@9164
   360
    vdkShowWindow(data->native_window);
slouken@9164
   361
#endif
slouken@9164
   362
    SDL_SetMouseFocus(window);
slouken@9164
   363
    SDL_SetKeyboardFocus(window);
slouken@9164
   364
}
slouken@9164
   365
slouken@9164
   366
void
slouken@9164
   367
VIVANTE_HideWindow(_THIS, SDL_Window * window)
slouken@9164
   368
{
slouken@9164
   369
#if SDL_VIDEO_DRIVER_VIVANTE_VDK
slouken@9164
   370
    SDL_WindowData *data = window->driverdata;
slouken@9164
   371
    vdkHideWindow(data->native_window);
slouken@9164
   372
#endif
slouken@9164
   373
}
slouken@9164
   374
slouken@9164
   375
/*****************************************************************************/
slouken@9164
   376
/* SDL Window Manager function                                               */
slouken@9164
   377
/*****************************************************************************/
slouken@9164
   378
SDL_bool
slouken@9164
   379
VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
slouken@9164
   380
{
slouken@9164
   381
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@10055
   382
    SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0);
slouken@9164
   383
slouken@9164
   384
    if (info->version.major == SDL_MAJOR_VERSION &&
slouken@9164
   385
        info->version.minor == SDL_MINOR_VERSION) {
slouken@9164
   386
        info->subsystem = SDL_SYSWM_VIVANTE;
slouken@10055
   387
        info->info.vivante.display = displaydata->native_display;
slouken@9164
   388
        info->info.vivante.window = data->native_window;
slouken@9164
   389
        return SDL_TRUE;
slouken@9164
   390
    } else {
philipp@10945
   391
        SDL_SetError("Application not compiled with SDL %d.%d",
slouken@9164
   392
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@9164
   393
        return SDL_FALSE;
slouken@9164
   394
    }
slouken@9164
   395
}
slouken@9164
   396
slouken@9164
   397
/*****************************************************************************/
slouken@9164
   398
/* SDL event functions                                                       */
slouken@9164
   399
/*****************************************************************************/
slouken@9164
   400
void VIVANTE_PumpEvents(_THIS)
slouken@9164
   401
{
slouken@9164
   402
#ifdef SDL_INPUT_LINUXEV
slouken@9164
   403
    SDL_EVDEV_Poll();
slouken@9164
   404
#endif
slouken@9164
   405
}
slouken@9164
   406
slouken@9164
   407
#endif /* SDL_VIDEO_DRIVER_VIVANTE */
slouken@9164
   408
slouken@9164
   409
/* vi: set ts=4 sw=4 expandtab: */