From f413a27b73d1e0ceaf0d31fc9615208f11645108 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Tue, 21 Feb 2012 11:43:08 +0100 Subject: [observer] Windows double buffer fixes DC's and GC's is not double buffered by default on windows, and there is a separate erase event which causes awful flickering when constant updating a window. Hack around wx (to be able to use wxBufferPaintDC), to avoid flickering on windows. This works on windows because there (and only there) wxGC:create/1 also takes a memoryDC as argument. --- lib/observer/src/observer_app_wx.erl | 20 +++++++++--- lib/observer/src/observer_perf_wx.erl | 59 +++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 24 deletions(-) (limited to 'lib/observer/src') diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl index 900fba911a..7eac2b8fab 100644 --- a/lib/observer/src/observer_app_wx.erl +++ b/lib/observer/src/observer_app_wx.erl @@ -108,11 +108,18 @@ init([Notebook, Parent]) -> wxPanel:connect(DrawingArea, left_up), wxPanel:connect(DrawingArea, left_dclick), wxPanel:connect(DrawingArea, right_down), + case os:type() of + {win32, _} -> %% Ignore erase on windows + wxPanel:connect(DrawingArea, erase_background, [{callback, fun(_,_) -> ok end}]); + _ -> ok + end, UseGC = haveGC(DrawingArea), - Font = case UseGC of - true -> wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT); - false -> wxFont:new(12,?wxFONTFAMILY_DECORATIVE,?wxFONTSTYLE_NORMAL,?wxFONTWEIGHT_NORMAL) + Font = case os:type() of + {unix,_} when UseGC -> + wxFont:new(12,?wxFONTFAMILY_DECORATIVE,?wxFONTSTYLE_NORMAL,?wxFONTWEIGHT_NORMAL); + _ -> + wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT) end, SelCol = wxSystemSettings:getColour(?wxSYS_COLOUR_HIGHLIGHT), GreyBrush = wxBrush:new({230,230,240}), @@ -231,7 +238,12 @@ handle_event(Event, _State) -> handle_sync_event(#wx{event = #wxPaint{}},_, #state{app_w=DA, app=App, sel=Sel, paint=Paint, usegc=UseGC}) -> %% PaintDC must be created in a callback to work on windows. - DC = wxPaintDC:new(DA), + IsWindows = element(1, os:type()) =:= win32, + %% Avoid Windows flickering hack + DC = if IsWindows -> wx:typeCast(wxBufferedPaintDC:new(DA), wxPaintDC); + true -> wxPaintDC:new(DA) + end, + IsWindows andalso wxDC:clear(DC), GC = case UseGC of true -> GC0 = ?wxGC:create(DC), diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl index c4659d1ea1..0de9785fb9 100644 --- a/lib/observer/src/observer_perf_wx.erl +++ b/lib/observer/src/observer_perf_wx.erl @@ -61,15 +61,15 @@ init([Notebook, Parent]) -> try Panel = wxPanel:new(Notebook), Main = wxBoxSizer:new(?wxVERTICAL), - - CPU = wxPanel:new(Panel, [{winid, ?RQ_W}, {style,?wxFULL_REPAINT_ON_RESIZE}]), + Style = ?wxFULL_REPAINT_ON_RESIZE bor ?wxCLIP_CHILDREN, + CPU = wxPanel:new(Panel, [{winid, ?RQ_W}, {style,Style}]), wxWindow:setBackgroundColour(CPU, ?wxWHITE), wxSizer:add(Main, CPU, [{flag, ?wxEXPAND bor ?wxALL}, {proportion, 1}, {border, 5}]), MemIO = wxBoxSizer:new(?wxHORIZONTAL), - MEM = wxPanel:new(Panel, [{winid, ?MEM_W}, {style,?wxFULL_REPAINT_ON_RESIZE}]), + MEM = wxPanel:new(Panel, [{winid, ?MEM_W}, {style,Style}]), wxWindow:setBackgroundColour(MEM, ?wxWHITE), - IO = wxPanel:new(Panel, [{winid, ?IO_W}, {style,?wxFULL_REPAINT_ON_RESIZE}]), + IO = wxPanel:new(Panel, [{winid, ?IO_W}, {style,Style}]), wxWindow:setBackgroundColour(IO, ?wxWHITE), wxSizer:add(MemIO, MEM, [{flag, ?wxEXPAND bor ?wxLEFT}, {proportion, 1}, {border, 5}]), @@ -82,20 +82,31 @@ init([Notebook, Parent]) -> wxPanel:connect(CPU, paint, [callback]), wxPanel:connect(IO, paint, [callback]), wxPanel:connect(MEM, paint, [callback]), + case os:type() of + {win32, _} -> %% Ignore erase on windows + wxPanel:connect(CPU, erase_background, [{callback, fun(_,_) -> ok end}]), + wxPanel:connect(IO, erase_background, [{callback, fun(_,_) -> ok end}]), + wxPanel:connect(MEM, erase_background, [{callback, fun(_,_) -> ok end}]); + _ -> ok + end, UseGC = haveGC(Panel), - Font = case UseGC of - true -> - %% Def font is really small when using Graphics contexts for some reason - %% Hardcode it - wxFont:new(12,?wxFONTFAMILY_DECORATIVE,?wxFONTSTYLE_NORMAL,?wxFONTWEIGHT_BOLD); - false -> - DefFont = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT), - DefSize = wxFont:getPointSize(DefFont), - DefFamily = wxFont:getFamily(DefFont), - wxFont:new(DefSize, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_BOLD) - end, - SmallFont = wxFont:new(10, ?wxFONTFAMILY_DECORATIVE, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL), + {Font, SmallFont} + = case os:type() of + {unix, _} when UseGC -> + %% Def font is really small when using Graphics contexts for some reason + %% Hardcode it + F = wxFont:new(12,?wxFONTFAMILY_DECORATIVE,?wxFONTSTYLE_NORMAL,?wxFONTWEIGHT_BOLD), + SF = wxFont:new(10, ?wxFONTFAMILY_DECORATIVE, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL), + {F, SF}; + _ -> + DefFont = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT), + DefSize = wxFont:getPointSize(DefFont), + DefFamily = wxFont:getFamily(DefFont), + F = wxFont:new(DefSize, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_BOLD), + SF = wxFont:new(DefSize-1, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL), + {F, SF} + end, BlackPen = wxPen:new({0,0,0}, [{width, 2}]), Pens = [wxPen:new(Col, [{width, 2}]) || Col <- tuple_to_list(colors())], process_flag(trap_exit, true), @@ -135,10 +146,18 @@ handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_, Panel =:= element(?MEM_W, Windows) -> ?MEM_W; Panel =:= element(?IO_W, Windows) -> ?IO_W end, - DC = wxPaintDC:new(Panel), - GC = case UseGC of - true -> ?wxGC:create(DC); - false -> DC + IsWindows = element(1, os:type()) =:= win32, + + DC = if IsWindows -> + %% Ugly hack to aviod flickering on windows, works on windows only + %% But the other platforms are doublebuffered by default + wx:typeCast(wxBufferedPaintDC:new(Panel), wxPaintDC); + true -> + wxPaintDC:new(Panel) + end, + IsWindows andalso wxDC:clear(DC), + GC = if UseGC -> ?wxGC:create(DC); + true -> DC end, %% Nothing is drawn until wxPaintDC is destroyed. try -- cgit v1.2.3