mirror of https://github.com/buggins/dlangui.git
drawbuf pixel storage optimizations - don't use GC: #499
This commit is contained in:
parent
513a98a332
commit
62ceed2870
|
@ -643,3 +643,76 @@ dstring normalizeEndOfLineCharacters(dstring s) {
|
|||
}
|
||||
return cast(dstring)res;
|
||||
}
|
||||
|
||||
/// C malloc allocated array wrapper
|
||||
struct MallocBuf(T) {
|
||||
import core.stdc.stdlib : realloc, free;
|
||||
private T * _allocated;
|
||||
private uint _allocatedSize;
|
||||
private uint _length;
|
||||
/// get pointer
|
||||
@property T * ptr() { return _allocated; }
|
||||
/// get length
|
||||
@property uint length() { return _length; }
|
||||
/// set new length
|
||||
@property void length(uint len) {
|
||||
if (len > _allocatedSize) {
|
||||
reserve(_allocatedSize ? len * 2 : len);
|
||||
}
|
||||
_length = len;
|
||||
}
|
||||
/// const array[index];
|
||||
T opIndex(uint index) const {
|
||||
assert(index < _length);
|
||||
return _allocated[index];
|
||||
}
|
||||
/// ref array[index];
|
||||
ref T opIndex(uint index) {
|
||||
assert(index < _length);
|
||||
return _allocated[index];
|
||||
}
|
||||
/// array[index] = value;
|
||||
void opIndexAssign(uint index, T value) {
|
||||
assert(index < _length);
|
||||
_allocated[index] = value;
|
||||
}
|
||||
/// array[index] = value;
|
||||
void opIndexAssign(uint index, T[] values) {
|
||||
assert(index + values.length < _length);
|
||||
_allocated[index .. index + values.length] = values[];
|
||||
}
|
||||
/// array[a..b]
|
||||
T[] opSlice(uint a, uint b) {
|
||||
assert(a <= b && b <= _length);
|
||||
return _allocated[a .. b];
|
||||
}
|
||||
/// array[]
|
||||
T[] opSlice() {
|
||||
return _allocated ? _allocated[0 .. _length] : null;
|
||||
}
|
||||
/// array[$]
|
||||
uint opDollar() { return _length; }
|
||||
~this() {
|
||||
clear();
|
||||
}
|
||||
/// free allocated memory, set length to 0
|
||||
void clear() {
|
||||
if (_allocated)
|
||||
free(_allocated);
|
||||
_allocatedSize = 0;
|
||||
_length = 0;
|
||||
}
|
||||
/// make sure buffer capacity is at least (size) items
|
||||
void reserve(uint size) {
|
||||
if (_allocatedSize < size) {
|
||||
_allocated = cast(T*)realloc(_allocated, T.sizeof * size);
|
||||
_allocatedSize = size;
|
||||
}
|
||||
}
|
||||
/// fill buffer with specified value
|
||||
void fill(T value) {
|
||||
if (_length) {
|
||||
_allocated[0 .. _length] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1233,14 +1233,15 @@ class ColorDrawBufBase : DrawBuf {
|
|||
}
|
||||
|
||||
class GrayDrawBuf : DrawBuf {
|
||||
int _dx;
|
||||
int _dy;
|
||||
protected int _dx;
|
||||
protected int _dy;
|
||||
/// returns buffer bits per pixel
|
||||
override @property int bpp() { return 8; }
|
||||
@property override int width() { return _dx; }
|
||||
@property override int height() { return _dy; }
|
||||
|
||||
ubyte[] _buf;
|
||||
protected MallocBuf!ubyte _buf;
|
||||
|
||||
this(int width, int height) {
|
||||
resize(width, height);
|
||||
}
|
||||
|
@ -1473,7 +1474,7 @@ class GrayDrawBuf : DrawBuf {
|
|||
}
|
||||
|
||||
class ColorDrawBuf : ColorDrawBufBase {
|
||||
uint[] _buf;
|
||||
protected MallocBuf!uint _buf;
|
||||
|
||||
/// create ARGB8888 draw buf of specified width and height
|
||||
this(int width, int height) {
|
||||
|
@ -1482,9 +1483,8 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
/// create copy of ColorDrawBuf
|
||||
this(ColorDrawBuf v) {
|
||||
this(v.width, v.height);
|
||||
//_buf.length = v._buf.length;
|
||||
foreach(i; 0 .. _buf.length)
|
||||
_buf[i] = v._buf[i];
|
||||
if (auto len = _buf.length)
|
||||
_buf.ptr[0 .. len] = v._buf.ptr[0 .. len];
|
||||
}
|
||||
/// create resized copy of ColorDrawBuf
|
||||
this(ColorDrawBuf v, int dx, int dy) {
|
||||
|
@ -1494,7 +1494,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
}
|
||||
|
||||
void invertAndPreMultiplyAlpha() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
uint a = (pixel >> 24) & 0xFF;
|
||||
uint r = (pixel >> 16) & 0xFF;
|
||||
uint g = (pixel >> 8) & 0xFF;
|
||||
|
@ -1510,12 +1510,12 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
}
|
||||
|
||||
void invertAlpha() {
|
||||
foreach(ref pixel; _buf)
|
||||
foreach(ref pixel; _buf[])
|
||||
pixel ^= 0xFF000000;
|
||||
}
|
||||
|
||||
void invertByteOrder() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
pixel = (pixel & 0xFF00FF00) |
|
||||
((pixel & 0xFF0000) >> 16) |
|
||||
((pixel & 0xFF) << 16);
|
||||
|
@ -1524,7 +1524,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
|
||||
// for passing of image to OpenGL texture
|
||||
void invertAlphaAndByteOrder() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
pixel = ((pixel & 0xFF00FF00) |
|
||||
((pixel & 0xFF0000) >> 16) |
|
||||
((pixel & 0xFF) << 16));
|
||||
|
@ -1643,9 +1643,9 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
uint[] tmpbuf;
|
||||
tmpbuf.length = _buf.length;
|
||||
// do horizontal blur
|
||||
blurOneDimension(_buf, tmpbuf, blurSize, true);
|
||||
blurOneDimension(_buf[], tmpbuf, blurSize, true);
|
||||
// then do vertical blur
|
||||
blurOneDimension(tmpbuf, _buf, blurSize, false);
|
||||
blurOneDimension(tmpbuf, _buf[], blurSize, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue