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 inout(COLOR)[] scanline(int y) inout 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!(Renderer.COLOR) 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 } 143 144 class ProceduralTextureSource : TextureSource 145 { 146 private Image!(Renderer.COLOR) cachedImage; 147 148 abstract void getSize(out int width, out int height); 149 150 override TextureCanvas getPixels() 151 { 152 if (!cachedImage.w) 153 { 154 int w, h; 155 getSize(w, h); 156 cachedImage.size(w, h); 157 drawTo(cachedImage.toRef()); 158 } 159 return cachedImage.toRef(); 160 } 161 }