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 alias StorageType = PlainStorageUnit!COLOR; 30 31 StorageType* pixels; 32 xy_t w, h, stride; 33 34 inout(StorageType)[] scanline(xy_t y) inout 35 { 36 assert(y>=0 && y<h); 37 return pixels[stride*y..stride*(y+1)]; 38 } 39 40 mixin DirectView; 41 } 42 43 /// True when this renderer can lock quickly (usually when it's rendering in software). 44 /*immutable*/ bool canFastLock; 45 46 /// Lock a 32-bit, BGRX/BGRA surface 47 abstract Bitmap fastLock(); 48 49 /// ditto 50 abstract Bitmap lock(); 51 52 /// Unlock what was previously locked 53 abstract void unlock(); 54 55 /// Finalize rendering and present it to the user (flip buffers etc.) 56 abstract void present(); 57 58 /// Destroy any bound resources 59 abstract void shutdown(); 60 61 // ********************************************************************** 62 63 abstract @property uint width(); 64 abstract @property uint height(); 65 66 abstract void putPixel(int x, int y, COLOR color); 67 68 struct Pixel { int x, y; COLOR color; } 69 void putPixels(Pixel[] pixels) 70 { 71 foreach (ref pixel; pixels) 72 putPixel(pixel.tupleof); 73 } 74 75 abstract void line(float x0, float y0, float x1, float y1, COLOR color); 76 void vline(int x, int y0, int y1, COLOR color) { line(x, y0, x, y1, color); } 77 void hline(int x0, int x1, int y, COLOR color) { line(x0, y, x1, y, color); } 78 79 abstract void fillRect(int x0, int y0, int x1, int y1, COLOR color); 80 abstract void fillRect(float x0, float y0, float x1, float y1, COLOR color); 81 82 abstract void clear(); 83 84 abstract void draw(int x, int y, TextureSource source, int u0, int v0, int u1, int v1); 85 abstract void draw(float x0, float y0, float x1, float y1, TextureSource source, int u0, int v0, int u1, int v1); 86 } 87 88 /// Uniquely identify private data owned by different renderers 89 enum Renderers 90 { 91 SDLSoftware, 92 SDLOpenGL, 93 SDL2, 94 max 95 } 96 97 /// Base class for all renderer-specific texture data 98 class TextureRenderData 99 { 100 bool destroyed; 101 uint textureVersion = 0; 102 103 static shared bool cleanupNeeded; 104 } 105 106 /// Base class for logical textures 107 class TextureSource 108 { 109 TextureRenderData[Renderers.max] renderData; 110 111 uint textureVersion = 1; 112 113 alias ImageRef!(Renderer.COLOR) TextureCanvas; 114 115 /// Used when the target pixel memory is already allocated 116 abstract void drawTo(TextureCanvas dest); 117 118 /// Used when a pointer is needed to existing pixel memory 119 abstract TextureCanvas getPixels(); 120 121 ~this() 122 { 123 foreach (r; renderData) 124 if (r) 125 r.destroyed = true; 126 TextureRenderData.cleanupNeeded = true; 127 } 128 } 129 130 class ImageTextureSource : TextureSource 131 { 132 Image!(Renderer.COLOR) image; 133 134 override void drawTo(TextureCanvas dest) 135 { 136 image.blitTo(dest); 137 } 138 139 override TextureCanvas getPixels() 140 { 141 return image.toRef(); 142 } 143 } 144 145 class ProceduralTextureSource : TextureSource 146 { 147 private Image!(Renderer.COLOR) cachedImage; 148 149 abstract void getSize(out int width, out int height); 150 151 override TextureCanvas getPixels() 152 { 153 if (!cachedImage.w) 154 { 155 int w, h; 156 getSize(w, h); 157 cachedImage.size(w, h); 158 drawTo(cachedImage.toRef()); 159 } 160 return cachedImage.toRef(); 161 } 162 }