CtrlCore: gtk3 DrawImage optimization, DragRect cleanup

git-svn-id: svn://ultimatepp.org/upp/trunk@14345 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2020-04-21 16:24:39 +00:00
parent 50c7118301
commit 85702ae3b9
8 changed files with 25 additions and 161 deletions

View file

@ -3,10 +3,6 @@ private:
friend struct MMCtrl;
friend struct MMImp;
friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, int type, int animation);
friend void FinishDragRect(Ctrl& q);
static int WndCaretTime;
static bool WndCaretVisible;
static bool local_dnd_copy;

View file

@ -1481,10 +1481,6 @@ enum {
DRAWDRAGRECT_SOLID, DRAWDRAGRECT_NORMAL, DRAWDRAGRECT_DASHED
};
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, int type, int animation);
void FinishDragRect(Ctrl& q);
bool PointLoop(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms);
bool PointLoop(Ctrl& ctrl, const Image& img);

View file

@ -160,9 +160,6 @@ _DBG_
static bool ProcessInvalids();
friend void InitGtkApp(int argc, char **argv, const char **envptr);
friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, int type, int animation);
friend void FinishDragRect(Ctrl& q);
friend void GuiPlatformGripResize(TopWindow *q);
public: // really private:

View file

@ -32,17 +32,18 @@ void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size srcsz,
struct ImageSysData {
Image img;
cairo_surface_t *surface;
cairo_surface_t *surface = NULL;
void Init(const Image& img);
void Init(const Image& m, cairo_surface_t *other);
~ImageSysData();
};
cairo_surface_t *CreateCairoSurface(const Image& img)
cairo_surface_t *CreateCairoSurface(const Image& img, cairo_surface_t *other)
{
Size isz = img.GetSize();
cairo_format_t fmt = CAIRO_FORMAT_ARGB32;
cairo_surface_t *surface = cairo_image_surface_create(fmt, isz.cx, isz.cy);
cairo_surface_t *surface = other ? cairo_surface_create_similar_image(other, fmt, isz.cx, isz.cy)
: cairo_image_surface_create(fmt, isz.cx, isz.cy);
cairo_surface_flush(surface);
byte *a = (byte *)cairo_image_surface_get_data(surface);
int stride = cairo_format_stride_for_width(fmt, isz.cx);
@ -54,10 +55,15 @@ cairo_surface_t *CreateCairoSurface(const Image& img)
return surface;
}
void ImageSysData::Init(const Image& m)
cairo_surface_t *CreateCairoSurface(const Image& img)
{
return CreateCairoSurface(img, NULL);
}
void ImageSysData::Init(const Image& m, cairo_surface_t *other)
{
img = m;
surface = CreateCairoSurface(img);
surface = CreateCairoSurface(m, other);
SysImageRealized(img);
}
@ -69,9 +75,10 @@ ImageSysData::~ImageSysData()
struct ImageSysDataMaker : LRUCache<ImageSysData, int64>::Maker {
Image img;
cairo_surface_t *other;
virtual int64 Key() const { return img.GetSerialId(); }
virtual int Make(ImageSysData& object) const { object.Init(img); return img.GetLength(); }
virtual int Make(ImageSysData& object) const { object.Init(img, other); return img.GetLength(); }
};
void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
@ -93,13 +100,13 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
}
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
m.img = img;
m.other = cairo_get_target(cr);
ImageSysData& sd = cache.Get(m);
if(!IsNull(color)) {
SetColor(color);
cairo_mask_surface(cr, sd.surface, x, y);
}
else {
RTIMESTOP("cairo_paint");
cairo_set_source_surface(cr, sd.surface, x, y);
cairo_paint(cr);
}

View file

@ -45,7 +45,7 @@ RectTracker::RectTracker(Ctrl& master)
maxrect = Rect(-100000, -100000, 100000, 100000);
keepratio = false;
cursorimage = Image::Arrow();
color = InvertColor;
color = Black();
pattern = DRAWDRAGRECT_NORMAL;
animation = 0;
rounder = NULL;

View file

@ -11,84 +11,6 @@ bool ScreenInPaletteMode()
return ScreenInfo().PaletteMode();
}
HRGN GetFrameRgn(const Rect& rect, int n) {
HRGN rgn = CreateRectRgnIndirect(rect);
Rect r = rect;
r.Deflate(n);
if(r.Width() > 0 && r.Height() > 0) {
HRGN rgnin = CreateRectRgnIndirect(r);
CombineRgn(rgn, rgn, rgnin, RGN_XOR);
DeleteObject(rgnin);
}
return rgn;
}
void DrawDragRect(SystemDraw& w, const Rect& _rect1, const Rect& _rect2, const Rect& _clip, int n, Color color, uint64 pattern)
{
Point o = w.GetOffset();
Rect rect1 = _rect1 + o;
Rect rect2 = _rect2 + o;
Rect clip = _clip + o;
HDC hdc = w.BeginGdi();
word wpat[8] = {
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
};
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
HBRUSH brush = ::CreatePatternBrush(bitmap);
DeleteObject(bitmap);
SetTextColor(hdc, color);
SetBkColor(hdc, SColorText());
Point offset;
#ifdef PLATFORM_WINCE
offset = Point(0, 0);
#else
::GetViewportOrgEx(hdc, offset);
#endif
HRGN rgn = GetFrameRgn(rect1 + offset, n);
HRGN rgn2 = GetFrameRgn(rect2 + offset, n);
HRGN cliprgn = CreateRectRgnIndirect(clip + offset);
CombineRgn(rgn, rgn, rgn2, RGN_XOR);
CombineRgn(rgn, rgn, cliprgn, RGN_AND);
SelectClipRgn(hdc, rgn);
Rect r;
GetClipBox(hdc, r);
HBRUSH obrush = (HBRUSH) SelectObject(hdc, brush);
PatBlt(hdc, r.left, r.top, r.Width(), r.Height(), PATINVERT);
SelectObject(hdc, obrush);
SelectClipRgn(hdc, NULL);
DeleteObject(rgn);
DeleteObject(rgn2);
DeleteObject(cliprgn);
ReleaseDC(NULL, hdc);
DeleteObject(brush);
w.EndGdi();
}
void FinishDragRect(Ctrl& q)
{
}
static uint64 sGetAniPat(uint64 src, int pos)
{
uint64 out = 0;
pos &= 7;
for(int i = 8; --i >= 0;) {
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
}
return out;
}
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, int type, int animation)
{
ViewDraw w(&q);
uint64 pattern = type == DRAWDRAGRECT_DASHED ? I64(0xf0783c1e0f87c3e1) :
type == DRAWDRAGRECT_NORMAL ? I64(0x55aa55aa55aa55aa) : 0;
DrawDragRect(w, rect1, rect2, clip, n, color, sGetAniPat(pattern, animation));
}
}
#endif

View file

@ -41,63 +41,4 @@ Vector<Rect> Xor(const Vector<Rect>& r1, const Vector<Rect>& r2)
return q;
}
Vector<Rect> GetFrameRgn(const Rect& rect, int n) {
Vector<Rect> q = RectRgn(rect);
q.Add(rect);
Rect r = rect;
r.Deflate(n);
if(r.Width() > 0 && r.Height() > 0)
q = Xor(q, RectRgn(r));
return q;
}
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, uint64 pattern)
{
char bd[8];
for(int i = 0; i < 8; i++)
bd[i] = ~(byte)(pattern >> (8 * (7 - i)));
Pixmap stipple = XCreateBitmapFromData(Xdisplay, w.GetDrawable(), bd, 8, 8);
Point offset = w.GetOffset();
GC gc = XCreateGC(Xdisplay, w.GetDrawable(), 0, 0);
SetClip(gc, w.GetXftDraw(),
Intersect(Xor(GetFrameRgn(rect1 + offset, n), GetFrameRgn(rect2 + offset, n)),
RectRgn(clip + offset)));
XGCValues gcv;
gcv.function = X11_ROP2_XOR;
gcv.foreground = GetXPixel(color);
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
XChangeGC(Xdisplay, gc, GCForeground|GCFunction|GCStipple|GCFillStyle, &gcv);
XFillRectangle(Xdisplay, w.GetDrawable(), gc, 0, 0, Xwidth, Xheight);
XFreePixmap(Xdisplay, stipple);
}
static uint64 sGetAniPat(uint64 src, int pos)
{
uint64 out = 0;
pos &= 7;
for(int i = 8; --i >= 0;) {
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
}
return out;
}
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, int type, int animation)
{
ViewDraw w(&q);
uint64 pattern = type == DRAWDRAGRECT_DASHED ? I64(0xf0783c1e0f87c3e1) :
type == DRAWDRAGRECT_NORMAL ? I64(0x55aa55aa55aa55aa) : 0;
DrawDragRect(w, rect1, rect2, clip, n, color, sGetAniPat(pattern, animation));
}
void FinishDragRect(Ctrl& q)
{
}
}
#endif

View file

@ -340,21 +340,26 @@ void DrawDragLine(Draw& w, bool horz, int x, int y, int len, int n, const int *p
else
w.Clip(x, y, n, len);
Color color2 = IsDark(color) ? White() : Black();
(horz ? x : y) -= animation;
len += animation;
bool ch = false;
while(len > 0) {
int segment = pattern[ch];
int d = segment + pattern[2];
int pause = pattern[2];
if(horz) {
w.DrawRect(x, y, segment, n, color);
x += d;
x += segment;
w.DrawRect(x, y, pause, n, color2);
x += pause;
}
else {
w.DrawRect(x, y, n, segment, color);
y += d;
y += segment;
w.DrawRect(x, y, n, pause, color2);
y += pause;
}
len -= d;
len -= pause + segment;
ch = !ch;
}
w.End();