1 /**
2  * ae.ui.video.renderer
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <vladimir@thecybershadow.net>
12  */
13 
14 module ae.ui.video.renderer;
15 
16 public import ae.utils.graphics.color;
17 public import ae.utils.graphics.image;
18 public import ae.utils.graphics.view;
19 
20 /// Abstract class for a video renderer.
21 class Renderer
22 {
23 	alias COLOR = BGRX;
24 
25 	/// BGRX/BGRA-only.
26 	struct Bitmap
27 	{
28 		static assert(COLOR.sizeof == uint.sizeof);
29 
30 		COLOR* pixels;
31 		int w, h, stride;
32 
33 		COLOR[] scanline(int y)
34 		{
35 			assert(y>=0 && y<h);
36 			return pixels[stride*y..stride*(y+1)];
37 		}
38 
39 		mixin DirectView;
40 	}
41 
42 	/// True when this renderer can lock quickly (usually when it's rendering in software).
43 	/*immutable*/ bool canFastLock;
44 
45 	/// Lock a 32-bit, BGRX/BGRA surface
46 	abstract Bitmap fastLock();
47 
48 	/// ditto
49 	abstract Bitmap lock();
50 
51 	/// Unlock what was previously locked
52 	abstract void unlock();
53 
54 	/// Finalize rendering and present it to the user (flip buffers etc.)
55 	abstract void present();
56 
57 	/// Destroy any bound resources
58 	abstract void shutdown();
59 
60 	// **********************************************************************
61 
62 	abstract @property uint width();
63 	abstract @property uint height();
64 
65 	abstract void putPixel(int x, int y, COLOR color);
66 
67 	struct Pixel { int x, y; COLOR color; }
68 	void putPixels(Pixel[] pixels)
69 	{
70 		foreach (ref pixel; pixels)
71 			putPixel(pixel.tupleof);
72 	}
73 
74 	abstract void line(float x0, float y0, float x1, float y1, COLOR color);
75 	void vline(int x, int y0, int y1, COLOR color) { line(x, y0, x, y1, color); }
76 	void hline(int x0, int x1, int y, COLOR color) { line(x0, y, x1, y, color); }
77 
78 	abstract void fillRect(int x0, int y0, int x1, int y1, COLOR color);
79 	abstract void fillRect(float x0, float y0, float x1, float y1, COLOR color);
80 
81 	abstract void clear();
82 
83 	abstract void draw(int x, int y, TextureSource source, int u0, int v0, int u1, int v1);
84 	abstract void draw(float x0, float y0, float x1, float y1, TextureSource source, int u0, int v0, int u1, int v1);
85 }
86 
87 /// Uniquely identify private data owned by different renderers
88 enum Renderers
89 {
90 	SDLSoftware,
91 	SDLOpenGL,
92 	SDL2,
93 	max
94 }
95 
96 /// Base class for all renderer-specific texture data
97 class TextureRenderData
98 {
99 	bool destroyed;
100 	uint textureVersion = 0;
101 
102 	static shared bool cleanupNeeded;
103 }
104 
105 /// Base class for logical textures
106 class TextureSource
107 {
108 	TextureRenderData[Renderers.max] renderData;
109 
110 	uint textureVersion = 1;
111 
112 	alias ImageRef!(Renderer.COLOR) TextureCanvas;
113 
114 	/// Used when the target pixel memory is already allocated
115 	abstract void drawTo(TextureCanvas dest);
116 
117 	/// Used when a pointer is needed to existing pixel memory
118 	abstract TextureCanvas getPixels();
119 
120 	~this()
121 	{
122 		foreach (r; renderData)
123 			if (r)
124 				r.destroyed = true;
125 		TextureRenderData.cleanupNeeded = true;
126 	}
127 }
128 
129 class ImageTextureSource : TextureSource
130 {
131 	Image!BGRX image;
132 
133 	override void drawTo(TextureCanvas dest)
134 	{
135 		image.blitTo(dest);
136 	}
137 
138 	override TextureCanvas getPixels()
139 	{
140 		return image.toRef();
141 	}
142 }