From 85702ae3b9ed1a031fc65e165d8c740619b3c780 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 21 Apr 2020 16:24:39 +0000 Subject: [PATCH] CtrlCore: gtk3 DrawImage optimization, DragRect cleanup git-svn-id: svn://ultimatepp.org/upp/trunk@14345 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/CocoCtrl.h | 4 -- uppsrc/CtrlCore/CtrlCore.h | 4 -- uppsrc/CtrlCore/GtkCtrl.h | 3 -- uppsrc/CtrlCore/GtkDrawImage.cpp | 23 ++++++---- uppsrc/CtrlCore/LocalLoop.cpp | 2 +- uppsrc/CtrlCore/UtilWin32.cpp | 78 -------------------------------- uppsrc/CtrlCore/UtilX11.cpp | 59 ------------------------ uppsrc/Draw/DrawUtil.cpp | 13 ++++-- 8 files changed, 25 insertions(+), 161 deletions(-) diff --git a/uppsrc/CtrlCore/CocoCtrl.h b/uppsrc/CtrlCore/CocoCtrl.h index 4d1863c99..1658c62fc 100644 --- a/uppsrc/CtrlCore/CocoCtrl.h +++ b/uppsrc/CtrlCore/CocoCtrl.h @@ -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; diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 93438a135..a2c42ae96 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -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& ani, int ani_ms); bool PointLoop(Ctrl& ctrl, const Image& img); diff --git a/uppsrc/CtrlCore/GtkCtrl.h b/uppsrc/CtrlCore/GtkCtrl.h index 4757f7525..72800db93 100644 --- a/uppsrc/CtrlCore/GtkCtrl.h +++ b/uppsrc/CtrlCore/GtkCtrl.h @@ -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: diff --git a/uppsrc/CtrlCore/GtkDrawImage.cpp b/uppsrc/CtrlCore/GtkDrawImage.cpp index d4ed2bdc2..d3f1c555d 100644 --- a/uppsrc/CtrlCore/GtkDrawImage.cpp +++ b/uppsrc/CtrlCore/GtkDrawImage.cpp @@ -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::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); } diff --git a/uppsrc/CtrlCore/LocalLoop.cpp b/uppsrc/CtrlCore/LocalLoop.cpp index 7e6d47e16..a585b649b 100644 --- a/uppsrc/CtrlCore/LocalLoop.cpp +++ b/uppsrc/CtrlCore/LocalLoop.cpp @@ -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; diff --git a/uppsrc/CtrlCore/UtilWin32.cpp b/uppsrc/CtrlCore/UtilWin32.cpp index 8f25d87a9..6daead016 100644 --- a/uppsrc/CtrlCore/UtilWin32.cpp +++ b/uppsrc/CtrlCore/UtilWin32.cpp @@ -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 diff --git a/uppsrc/CtrlCore/UtilX11.cpp b/uppsrc/CtrlCore/UtilX11.cpp index 774b5707a..dc19f4122 100644 --- a/uppsrc/CtrlCore/UtilX11.cpp +++ b/uppsrc/CtrlCore/UtilX11.cpp @@ -41,63 +41,4 @@ Vector Xor(const Vector& r1, const Vector& r2) return q; } -Vector GetFrameRgn(const Rect& rect, int n) { - Vector 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 diff --git a/uppsrc/Draw/DrawUtil.cpp b/uppsrc/Draw/DrawUtil.cpp index b7103f533..516b0a699 100644 --- a/uppsrc/Draw/DrawUtil.cpp +++ b/uppsrc/Draw/DrawUtil.cpp @@ -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();