SDL  2.0
SDL_emscriptenframebuffer.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_EMSCRIPTEN
24 
25 #include "SDL_emscriptenvideo.h"
27 
28 
30 {
31  SDL_Surface *surface;
32  const Uint32 surface_format = SDL_PIXELFORMAT_BGR888;
33  int w, h;
34  int bpp;
35  Uint32 Rmask, Gmask, Bmask, Amask;
36 
37  /* Free the old framebuffer surface */
39  surface = data->surface;
40  SDL_FreeSurface(surface);
41 
42  /* Create a new one */
43  SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
44  SDL_GetWindowSize(window, &w, &h);
45 
46  surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
47  if (!surface) {
48  return -1;
49  }
50 
51  /* Save the info and return! */
52  data->surface = surface;
53  *format = surface_format;
54  *pixels = surface->pixels;
55  *pitch = surface->pitch;
56  return 0;
57 }
58 
59 int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
60 {
61  SDL_Surface *surface;
62 
63  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
64  surface = data->surface;
65  if (!surface) {
66  return SDL_SetError("Couldn't find framebuffer surface for window");
67  }
68 
69  /* Send the data to the display */
70 
71  EM_ASM_INT({
72  //TODO: don't create context every update
73  var ctx = Module['canvas'].getContext('2d');
74 
75  //library_sdl.js SDL_UnlockSurface
76  var image = ctx.createImageData($0, $1);
77  var data = image.data;
78  var src = $2 >> 2;
79  var dst = 0;
80  var isScreen = true;
81  var num;
82  if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) {
83  // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray,
84  // not UInt8ClampedArray. These don't have buffers, so we need to revert
85  // to copying a byte at a time. We do the undefined check because modern
86  // browsers do not define CanvasPixelArray anymore.
87  num = data.length;
88  while (dst < num) {
89  var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
90  data[dst ] = val & 0xff;
91  data[dst+1] = (val >> 8) & 0xff;
92  data[dst+2] = (val >> 16) & 0xff;
93  data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff);
94  src++;
95  dst += 4;
96  }
97  } else {
98  var data32 = new Uint32Array(data.buffer);
99  num = data32.length;
100  if (isScreen) {
101  while (dst < num) {
102  // HEAP32[src++] is an optimization. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
103  data32[dst++] = HEAP32[src++] | 0xff000000;
104  }
105  } else {
106  while (dst < num) {
107  data32[dst++] = HEAP32[src++];
108  }
109  }
110  }
111 
112  ctx.putImageData(image, 0, 0);
113  return 0;
114  }, surface->w, surface->h, surface->pixels);
115 
116  /*if (SDL_getenv("SDL_VIDEO_Emscripten_SAVE_FRAMES")) {
117  static int frame_number = 0;
118  char file[128];
119  SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
120  SDL_GetWindowID(window), ++frame_number);
121  SDL_SaveBMP(surface, file);
122  }*/
123  return 0;
124 }
125 
127 {
128  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
129 
130  SDL_FreeSurface(data->surface);
131  data->surface = NULL;
132 }
133 
134 #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
135 
136 /* vi: set ts=4 sw=4 expandtab: */
GLenum GLenum dst
GLuint num
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
GLeglImageOES image
Definition: SDL_opengl.h:2141
SDL_Window * window
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
SDL_Surface * surface
#define SDL_GetWindowSize
int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
GLuint GLfloat * val
void * pixels
Definition: SDL_surface.h:75
#define SDL_FreeSurface
#define _THIS
#define SDL_PixelFormatEnumToMasks
#define NULL
Definition: begin_code.h:143
#define SDL_SetError
#define SDL_CreateRGBSurface
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_Rect rects[MAX_RECTS]
GLubyte GLubyte GLubyte GLubyte w
void * driverdata
Definition: SDL_sysvideo.h:106
int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
GLenum src
GLfloat GLfloat GLfloat GLfloat h
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64