Initial support for software rendering using Cairo

This commit is contained in:
Joshua Granick
2015-05-01 18:13:40 -07:00
parent 491a15a7e9
commit 6e705aa23f
14 changed files with 325 additions and 156 deletions

View File

@@ -209,6 +209,7 @@ class NativeApplication {
case RENDER:
parent.renderer.render ();
parent.renderer.onRender.dispatch (parent.renderer.context);
parent.renderer.flip ();
@@ -222,7 +223,11 @@ class NativeApplication {
#if lime_console
parent.renderer.context = CONSOLE (new ConsoleRenderContext ());
#else
parent.renderer.context = OPENGL (new GLRenderContext ());
if (parent.config.hardware) {
parent.renderer.context = OPENGL (new GLRenderContext ());
}
#end
parent.renderer.onRenderContextRestored.dispatch (parent.renderer.context);

View File

@@ -1,6 +1,10 @@
package lime._backend.native;
import lime.graphics.cairo.Cairo;
import lime.graphics.cairo.CairoFormat;
import lime.graphics.cairo.CairoSurface;
import lime.graphics.CairoRenderContext;
import lime.graphics.ConsoleRenderContext;
import lime.graphics.GLRenderContext;
import lime.graphics.Renderer;
@@ -15,6 +19,12 @@ class NativeRenderer {
public var handle:Dynamic;
private var parent:Renderer;
private var useHardware:Bool;
#if lime_cairo
private var cairo:Cairo;
private var primarySurface:CairoSurface;
#end
public function new (parent:Renderer) {
@@ -28,10 +38,20 @@ class NativeRenderer {
handle = lime_renderer_create (parent.window.backend.handle);
useHardware = parent.window.config.hardware;
#if lime_console
parent.context = CONSOLE (new ConsoleRenderContext ());
#else
parent.context = OPENGL (new GLRenderContext ());
if (useHardware) {
parent.context = OPENGL (new GLRenderContext ());
} else {
render ();
}
#end
}
@@ -46,6 +66,19 @@ class NativeRenderer {
public function flip ():Void {
if (!useHardware) {
lime_renderer_unlock (handle);
#if lime_cairo
if (cairo != null) {
primarySurface.flush ();
}
#end
}
lime_renderer_flip (handle);
}
@@ -53,7 +86,25 @@ class NativeRenderer {
public function render ():Void {
if (!useHardware) {
#if lime_cairo
if (cairo != null) {
cairo.destroy ();
primarySurface.destroy ();
}
var lock = lime_renderer_lock (handle);
primarySurface = CairoSurface.createForData (lock.pixels, CairoFormat.ARGB32, lock.width, lock.height, lock.pitch);
cairo = new Cairo (primarySurface);
parent.context = CAIRO (cairo);
#else
parent.context = NONE;
#end
}
}
@@ -67,6 +118,8 @@ class NativeRenderer {
private static var lime_renderer_create = System.load ("lime", "lime_renderer_create", 1);
private static var lime_renderer_flip = System.load ("lime", "lime_renderer_flip", 1);
private static var lime_renderer_lock = System.load ("lime", "lime_renderer_lock", 1);
private static var lime_renderer_unlock = System.load ("lime", "lime_renderer_unlock", 1);
}

View File

@@ -3,6 +3,7 @@ package lime._backend.native;
import lime.app.Application;
import lime.graphics.Image;
import lime.graphics.ImageBuffer;
import lime.system.System;
import lime.ui.Window;
@@ -61,6 +62,7 @@ class NativeWindow {
if (Reflect.hasField (parent.config, "borderless") && parent.config.borderless) flags |= cast WindowFlags.WINDOW_FLAG_BORDERLESS;
if (Reflect.hasField (parent.config, "depthBuffer") && parent.config.depthBuffer) flags |= cast WindowFlags.WINDOW_FLAG_DEPTH_BUFFER;
if (Reflect.hasField (parent.config, "fullscreen") && parent.config.fullscreen) flags |= cast WindowFlags.WINDOW_FLAG_FULLSCREEN;
if (Reflect.hasField (parent.config, "hardware") && parent.config.hardware) flags |= cast WindowFlags.WINDOW_FLAG_HARDWARE;
if (Reflect.hasField (parent.config, "resizable") && parent.config.resizable) flags |= cast WindowFlags.WINDOW_FLAG_RESIZABLE;
if (Reflect.hasField (parent.config, "stencilBuffer") && parent.config.stencilBuffer) flags |= cast WindowFlags.WINDOW_FLAG_STENCIL_BUFFER;
if (Reflect.hasField (parent.config, "vsync") && parent.config.vsync) flags |= cast WindowFlags.WINDOW_FLAG_VSYNC;

View File

@@ -17,6 +17,7 @@ typedef Config = {
@:optional var file:String;
@:optional var fps:Int;
@:optional var fullscreen:Bool;
@:optional var hardware:Bool;
@:optional var height:Int;
@:optional var orientation:String;
@:optional var packageName:String;

View File

@@ -1,44 +1,47 @@
package lime.graphics;
import lime.graphics.cairo.Cairo;
import lime.graphics.cairo.CairoFormat;
import lime.graphics.cairo.CairoSurface;
class CairoRenderContext {
public var version (get, null):Int;
public var versionString (get, null):String;
public function new () {
}
// Get & Set Methods
private inline function get_version ():Int {
return Cairo.version;
}
private function get_versionString ():String {
return Cairo.versionString;
}
}
typedef CairoRenderContext = lime.graphics.cairo.Cairo;
//
//
//import lime.graphics.cairo.Cairo;
//import lime.graphics.cairo.CairoFormat;
//import lime.graphics.cairo.CairoSurface;
//
//
//class CairoRenderContext {
//
//
//public var version (get, null):Int;
//public var versionString (get, null):String;
//
//
//public function new () {
//
//
//
//}
//
//
//
//
//// Get & Set Methods
//
//
//
//
//private inline function get_version ():Int {
//
//return Cairo.version;
//
//}
//
//
//private function get_versionString ():String {
//
//return Cairo.versionString;
//
//}
//
//
//}

View File

@@ -7,6 +7,7 @@ import lime.graphics.DOMRenderContext;
import lime.graphics.FlashRenderContext;
import lime.graphics.GLRenderContext;
enum RenderContext {
OPENGL (gl:GLRenderContext);
@@ -16,5 +17,6 @@ enum RenderContext {
CAIRO (cairo:CairoRenderContext);
CONSOLE (context:ConsoleRenderContext);
CUSTOM (data:Dynamic);
NONE;
}

View File

@@ -38,6 +38,15 @@ abstract CairoSurface(Dynamic) {
}
public function flush ():Void {
#if lime_cairo
lime_cairo_surface_flush (this);
#end
}
// Native Methods
@@ -49,6 +58,7 @@ abstract CairoSurface(Dynamic) {
private static var lime_cairo_image_surface_create = System.load ("lime", "lime_cairo_image_surface_create", 3);
private static var lime_cairo_image_surface_create_for_data = System.load ("lime", "lime_cairo_image_surface_create_for_data", 5);
private static var lime_cairo_surface_destroy = System.load ("lime", "lime_cairo_surface_destroy", 1);
private static var lime_cairo_surface_flush = System.load ("lime", "lime_cairo_surface_flush", 1);
#end

View File

@@ -3,6 +3,7 @@
#include <ui/Window.h>
#include <hx/CFFI.h>
namespace lime {
@@ -14,6 +15,8 @@ namespace lime {
public:
virtual void Flip () = 0;
virtual value Lock () = 0;
virtual void Unlock () = 0;
Window* currentWindow;

View File

@@ -708,6 +708,21 @@ namespace lime {
}
value lime_renderer_lock (value renderer) {
return ((Renderer*)(intptr_t)val_float (renderer))->Lock ();
}
value lime_renderer_unlock (value renderer) {
((Renderer*)(intptr_t)val_float (renderer))->Unlock ();
return alloc_null ();
}
value lime_system_get_directory (value type, value company, value title) {
const char* companyName = "";
@@ -987,6 +1002,8 @@ namespace lime {
DEFINE_PRIM (lime_neko_execute, 1);
DEFINE_PRIM (lime_renderer_create, 1);
DEFINE_PRIM (lime_renderer_flip, 1);
DEFINE_PRIM (lime_renderer_lock, 1);
DEFINE_PRIM (lime_renderer_unlock, 1);
DEFINE_PRIM (lime_render_event_manager_register, 2);
DEFINE_PRIM (lime_system_get_directory, 3);
DEFINE_PRIM (lime_system_get_timer, 0);

View File

@@ -10,8 +10,19 @@ namespace lime {
currentWindow = window;
sdlWindow = ((SDLWindow*)window)->sdlWindow;
sdlTexture = 0;
int sdlFlags = SDL_RENDERER_ACCELERATED;
int sdlFlags = 0;
if (window->flags & WINDOW_FLAG_HARDWARE) {
sdlFlags |= SDL_RENDERER_ACCELERATED;
} else {
sdlFlags |= SDL_RENDERER_SOFTWARE;
}
if (window->flags & WINDOW_FLAG_VSYNC) sdlFlags |= SDL_RENDERER_PRESENTVSYNC;
@@ -46,6 +57,51 @@ namespace lime {
}
value SDLRenderer::Lock () {
int width;
int height;
SDL_GetRendererOutputSize (sdlRenderer, &width, &height);
if (!sdlTexture) {
sdlTexture = SDL_CreateTexture (sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height);
}
value result = alloc_empty_object ();
void *pixels;
int pitch;
if (SDL_LockTexture (sdlTexture, NULL, &pixels, &pitch) == 0) {
alloc_field (result, val_id ("width"), alloc_int (width));
alloc_field (result, val_id ("height"), alloc_int (height));
alloc_field (result, val_id ("pixels"), alloc_float ((intptr_t)pixels));
alloc_field (result, val_id ("pitch"), alloc_int (pitch));
}
return result;
}
void SDLRenderer::Unlock () {
if (sdlTexture) {
SDL_UnlockTexture (sdlTexture);
SDL_RenderClear (sdlRenderer);
SDL_RenderCopy (sdlRenderer, sdlTexture, NULL, NULL);
}
}
Renderer* CreateRenderer (Window* window) {
return new SDLRenderer (window);

View File

@@ -17,8 +17,11 @@ namespace lime {
~SDLRenderer ();
virtual void Flip ();
virtual value Lock ();
virtual void Unlock ();
SDL_Renderer* sdlRenderer;
SDL_Texture* sdlTexture;
SDL_Window* sdlWindow;
};

View File

@@ -16,42 +16,46 @@ namespace lime {
currentApplication = application;
this->flags = flags;
int sdlFlags = SDL_WINDOW_OPENGL;
int sdlFlags = 0;
if (flags & WINDOW_FLAG_FULLSCREEN) sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
if (flags & WINDOW_FLAG_RESIZABLE) sdlFlags |= SDL_WINDOW_RESIZABLE;
if (flags & WINDOW_FLAG_BORDERLESS) sdlFlags |= SDL_WINDOW_BORDERLESS;
#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
if (flags & WINDOW_FLAG_HARDWARE) {
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_SetHint (SDL_HINT_VIDEO_WIN_D3DCOMPILER, "d3dcompiler_47.dll");
sdlFlags |= SDL_WINDOW_OPENGL;
#endif
#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_SetHint (SDL_HINT_VIDEO_WIN_D3DCOMPILER, "d3dcompiler_47.dll");
#endif
if (flags & WINDOW_FLAG_DEPTH_BUFFER) {
if (flags & WINDOW_FLAG_DEPTH_BUFFER) {
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32 - (flags & WINDOW_FLAG_STENCIL_BUFFER) ? 8 : 0);
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32 - (flags & WINDOW_FLAG_STENCIL_BUFFER) ? 8 : 0);
}
}
if (flags & WINDOW_FLAG_STENCIL_BUFFER) {
if (flags & WINDOW_FLAG_STENCIL_BUFFER) {
SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
}
}
if (flags & WINDOW_FLAG_HW_AA_HIRES) {
if (flags & WINDOW_FLAG_HW_AA_HIRES) {
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 4);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 4);
} else if (flags & WINDOW_FLAG_HW_AA) {
} else if (flags & WINDOW_FLAG_HW_AA) {
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 2);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 2);
}
}

View File

@@ -175,6 +175,74 @@ namespace lime {
}
value lime_cairo_pattern_create_for_surface (value surface) {
return alloc_float ((intptr_t)cairo_pattern_create_for_surface ((cairo_surface_t*)(intptr_t)val_float (surface)));
}
value lime_cairo_pattern_destroy (value handle) {
cairo_pattern_destroy ((cairo_pattern_t*)(intptr_t)val_float (handle));
return alloc_null ();
}
value lime_cairo_pattern_get_extend (value handle) {
return alloc_int (cairo_pattern_get_extend ((cairo_pattern_t*)(intptr_t)val_float (handle)));
}
value lime_cairo_pattern_set_extend (value handle, value extend) {
cairo_pattern_set_extend ((cairo_pattern_t*)(intptr_t)val_float (handle), (cairo_extend_t)val_int (extend));
return alloc_null ();
}
value lime_cairo_pattern_get_filter (value handle) {
return alloc_int (cairo_pattern_get_filter ((cairo_pattern_t*)(intptr_t)val_float (handle)));
}
value lime_cairo_pattern_set_filter (value handle, value filter) {
cairo_pattern_set_filter ((cairo_pattern_t*)(intptr_t)val_float (handle), (cairo_filter_t)val_int (filter));
return alloc_null ();
}
value lime_cairo_pattern_get_matrix (value handle) {
cairo_matrix_t cm;
cairo_pattern_get_matrix ((cairo_pattern_t*)(intptr_t)val_float (handle), &cm);
Matrix3 mat3 = Matrix3 (cm.xx, cm.yx, cm.xy, cm.yy, cm.x0, cm.y0);
return mat3.Value ();
}
value lime_cairo_pattern_set_matrix (value handle, value matrix) {
Matrix3 mat3 = Matrix3 (matrix);
cairo_matrix_t cm;
cairo_matrix_init (&cm, mat3.a, mat3.b, mat3.c, mat3.d, mat3.tx, mat3.ty);
cairo_pattern_set_matrix ((cairo_pattern_t*)(intptr_t)val_float (handle), &cm);
return alloc_null ();
}
value lime_cairo_pop_group (value handle) {
return alloc_float ((intptr_t)cairo_pop_group ((cairo_t*)(intptr_t)val_float (handle)));
@@ -339,6 +407,22 @@ namespace lime {
}
value lime_cairo_surface_destroy (value handle) {
cairo_surface_destroy ((cairo_surface_t*)(intptr_t)val_float (handle));
return alloc_null ();
}
value lime_cairo_surface_flush (value handle) {
cairo_surface_flush ((cairo_surface_t*)(intptr_t)val_float (handle));
return alloc_null ();
}
value lime_cairo_transform (value handle, value matrix) {
Matrix3 mat3 = Matrix3 (matrix);
@@ -352,82 +436,6 @@ namespace lime {
}
value lime_cairo_pattern_create_for_surface (value surface) {
return alloc_float ((intptr_t)cairo_pattern_create_for_surface ((cairo_surface_t*)(intptr_t)val_float (surface)));
}
value lime_cairo_pattern_destroy (value handle) {
cairo_pattern_destroy ((cairo_pattern_t*)(intptr_t)val_float (handle));
return alloc_null ();
}
value lime_cairo_pattern_get_extend (value handle) {
return alloc_int (cairo_pattern_get_extend ((cairo_pattern_t*)(intptr_t)val_float (handle)));
}
value lime_cairo_pattern_set_extend (value handle, value extend) {
cairo_pattern_set_extend ((cairo_pattern_t*)(intptr_t)val_float (handle), (cairo_extend_t)val_int (extend));
return alloc_null ();
}
value lime_cairo_pattern_get_filter (value handle) {
return alloc_int (cairo_pattern_get_filter ((cairo_pattern_t*)(intptr_t)val_float (handle)));
}
value lime_cairo_pattern_set_filter (value handle, value filter) {
cairo_pattern_set_filter ((cairo_pattern_t*)(intptr_t)val_float (handle), (cairo_filter_t)val_int (filter));
return alloc_null ();
}
value lime_cairo_pattern_get_matrix (value handle) {
cairo_matrix_t cm;
cairo_pattern_get_matrix ((cairo_pattern_t*)(intptr_t)val_float (handle), &cm);
Matrix3 mat3 = Matrix3 (cm.xx, cm.yx, cm.xy, cm.yy, cm.x0, cm.y0);
return mat3.Value ();
}
value lime_cairo_pattern_set_matrix (value handle, value matrix) {
Matrix3 mat3 = Matrix3 (matrix);
cairo_matrix_t cm;
cairo_matrix_init (&cm, mat3.a, mat3.b, mat3.c, mat3.d, mat3.tx, mat3.ty);
cairo_pattern_set_matrix ((cairo_pattern_t*)(intptr_t)val_float (handle), &cm);
return alloc_null ();
}
value lime_cairo_surface_destroy (value handle) {
cairo_surface_destroy ((cairo_surface_t*)(intptr_t)val_float (handle));
return alloc_null ();
}
value lime_cairo_version () {
return alloc_int (cairo_version ());
@@ -464,6 +472,14 @@ namespace lime {
DEFINE_PRIM (lime_cairo_new_path, 1);
DEFINE_PRIM (lime_cairo_paint, 1);
DEFINE_PRIM (lime_cairo_paint_with_alpha, 2);
DEFINE_PRIM (lime_cairo_pattern_create_for_surface, 1);
DEFINE_PRIM (lime_cairo_pattern_destroy, 1);
DEFINE_PRIM (lime_cairo_pattern_get_extend, 1);
DEFINE_PRIM (lime_cairo_pattern_get_filter, 1);
DEFINE_PRIM (lime_cairo_pattern_get_matrix, 1);
DEFINE_PRIM (lime_cairo_pattern_set_extend, 2);
DEFINE_PRIM (lime_cairo_pattern_set_filter, 2);
DEFINE_PRIM (lime_cairo_pattern_set_matrix, 2);
DEFINE_PRIM (lime_cairo_pop_group, 1);
DEFINE_PRIM (lime_cairo_pop_group_to_source, 1);
DEFINE_PRIM (lime_cairo_push_group, 1);
@@ -484,16 +500,9 @@ namespace lime {
DEFINE_PRIM (lime_cairo_set_source_surface, 4);
DEFINE_PRIM (lime_cairo_stroke, 1);
DEFINE_PRIM (lime_cairo_stroke_preserve, 1);
DEFINE_PRIM (lime_cairo_transform, 2);
DEFINE_PRIM (lime_cairo_pattern_create_for_surface, 1);
DEFINE_PRIM (lime_cairo_pattern_destroy, 1);
DEFINE_PRIM (lime_cairo_pattern_get_extend, 1);
DEFINE_PRIM (lime_cairo_pattern_get_filter, 1);
DEFINE_PRIM (lime_cairo_pattern_get_matrix, 1);
DEFINE_PRIM (lime_cairo_pattern_set_extend, 2);
DEFINE_PRIM (lime_cairo_pattern_set_filter, 2);
DEFINE_PRIM (lime_cairo_pattern_set_matrix, 2);
DEFINE_PRIM (lime_cairo_surface_destroy, 1);
DEFINE_PRIM (lime_cairo_surface_flush, 1);
DEFINE_PRIM (lime_cairo_transform, 2);
DEFINE_PRIM (lime_cairo_version, 0);
DEFINE_PRIM (lime_cairo_version_string, 0);

View File

@@ -69,6 +69,7 @@ class ApplicationMain {
file: "::APP_FILE::",
fps: Std.int (::WIN_FPS::),
fullscreen: ::WIN_FULLSCREEN::,
hardware: ::WIN_HARDWARE::,
height: Std.int (::WIN_HEIGHT::),
orientation: "::WIN_ORIENTATION::",
packageName: "::META_PACKAGE_NAME::",