added 2 changesets to branch 'refs/remotes/looncraz-github/CAP-dirty' old head: 0d8212774ea54be930014973d933c00ea30224d0 new head: 70f5d8fd08ae5b241a14129ad4b4b670e624dbfe overview: https://github.com/looncraz/haiku/compare/0d8212774ea5...70f5d8fd08ae ---------------------------------------------------------------------------- a589015fe935: Use CompositeWindowHWInterface create DrawingEngines Had to modify CompositeWindow construction slightly. Updated capset to provide cleaner output and check for proper value even in set state accumulation loop. Implement CompositeWindowHWInterface SetCopyToBackEnabled() 70f5d8fd08ae: Initialized buffers to NULL [ looncraz <looncraz@xxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 10 files changed, 284 insertions(+), 115 deletions(-) src/bin/capset/capset.cpp | 26 ++- src/servers/app/Desktop.cpp | 5 +- src/servers/app/ServerWindow.cpp | 19 +- src/servers/app/drawing/WindowBuffer.cpp | 51 +++-- src/servers/app/drawing/WindowBuffer.h | 5 +- .../drawing/interface/local/CompositeEngine.cpp | 3 - .../drawing/interface/local/CompositeWindow.cpp | 193 ++++++++++++++----- .../drawing/interface/local/CompositeWindow.h | 13 +- .../local/CompositeWindowHWInterface.cpp | 75 ++++++- .../interface/local/CompositeWindowHWInterface.h | 9 +- ############################################################################ Commit: a589015fe935df77c32ecf9dbca7c28e7057be7e Author: looncraz <looncraz@xxxxxxxxxxxx> Date: Thu Mar 26 19:28:44 2015 UTC Use CompositeWindowHWInterface create DrawingEngines Had to modify CompositeWindow construction slightly. Updated capset to provide cleaner output and check for proper value even in set state accumulation loop. Implement CompositeWindowHWInterface SetCopyToBackEnabled() ---------------------------------------------------------------------------- diff --git a/src/bin/capset/capset.cpp b/src/bin/capset/capset.cpp index 28dc281..ebcd9ce 100644 --- a/src/bin/capset/capset.cpp +++ b/src/bin/capset/capset.cpp @@ -292,14 +292,24 @@ int main(int argc, char**argv) continue; } else if (command.op == "-set") { if (command.object == "enabled") { - if ((command.value == "0" - || command.value == "false") - && capState.enabled) { - capState.enabled = false; - sendState = true; - } else if (!capState.enabled) { - capState.enabled = true; - sendState = true; + if (command.value == "0" + || command.value == "false") { + if (capState.enabled) { + capState.enabled = false; + sendState = true; + } else + printf("Compositing already disabled\n"); + } else if (command.value == "1" + || command.value == "true") { + if (!capState.enabled) { + capState.enabled = true; + sendState = true; + } else + printf("Compositing already enabled\n"); + } else { + fprintf(stderr, "Bad value on set:enabled (%s) invalid\n", + command.value.String()); + return 3; } } diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 4ddde91..517b0e0 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -2844,10 +2844,12 @@ Desktop::SetCompositingEnabled(bool enable) return B_NO_MEMORY; } error = fCompositeEngine->SetEnabled(true); + // Falls-through, does not unlock! } else { error = fCompositeEngine->SetEnabled(false); delete fCompositeEngine; fCompositeEngine = NULL; + // Falls-through, does not unlock! } @@ -2865,7 +2867,8 @@ Desktop::SetCompositingEnabled(bool enable) would be when a translucent window is above an update, the composite engine will have to make those areas a higher priority or risk flickering. Or we need to otherwise buffer the draws in - those cases. + those cases - Tracker can absolutely be cooperative in this + endeavor, but should consult the mailing list (or Axel) first. */ CompositeWindow* window = dynamic_cast<CompositeWindow*>(AllWindows().FirstWindow()); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index cbce763..c11f7b8 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -3632,27 +3632,16 @@ ServerWindow::MakeWindow(BRect frame, const char* name, ::HWInterface* windowHWInterface = NULL; - if (fDesktop->IsCompositingEnabled()) + if (fDesktop->IsCompositingEnabled()) { windowHWInterface - = new (std::nothrow) CompositeWindowHWInterface(fDesktop); - else + = new(std::nothrow) CompositeWindowHWInterface(fDesktop); + windowHWInterface->Initialize(); + } else windowHWInterface = fDesktop->HWInterface(); - windowHWInterface->Initialize(); - ::CompositeWindow* window = new(std::nothrow) ::CompositeWindow(frame, name, look, feel, flags, workspace, this, windowHWInterface); - // TEMPORARY TEST - single window set WindowBuffer - // TODO: change test to ensure B_NO_BUFFERED_DRAWING is NOT set in - // flags, test to see if app_server settings has buffered windowing - // OR compositing enabled... - - if (!strcmp("loon-buftest", name) || !strcmp("Chart", name)) { - window->SetWindowBufferEnabled(true); - _LOGF("Buffered Window created: %s\n", name); - } - return window; } diff --git a/src/servers/app/drawing/WindowBuffer.cpp b/src/servers/app/drawing/WindowBuffer.cpp index 397c434..64a25fc 100644 --- a/src/servers/app/drawing/WindowBuffer.cpp +++ b/src/servers/app/drawing/WindowBuffer.cpp @@ -23,6 +23,7 @@ WindowBuffer::WindowBuffer(Window* window) fWindow(window), fBuffer(NULL) { + CAPTRACE("new buffer\n"); fBounds.OffsetBy(-fBounds.left, -fBounds.top); _NewWindowSize(&fWidth, &fHeight); @@ -34,6 +35,7 @@ WindowBuffer::WindowBuffer(Window* window) WindowBuffer::~WindowBuffer() { + CAPTRACE("delete buffer\n"); fLock.Lock(); free(fBuffer); } @@ -57,6 +59,18 @@ WindowBuffer::ResizeTo(int32 width, int32 height) } +void +WindowBuffer::ResizeBy(int32 x, int32 y) +{ + BAutolock _(fLock); + int32 newWidth = fWidth + x; + int32 newHeight = fHeight + y; + + if (_NewWindowSize(&newWidth, &newHeight)) + _ResizeTo(newWidth, newHeight); +} + + // #pragma mark - @@ -64,56 +78,56 @@ WindowBuffer::ResizeTo(int32 width, int32 height) void WindowBuffer::ConvertToBuffer(BRect* rect) const { - + } void WindowBuffer::ConvertToBuffer(BPoint* point) const { - + } void WindowBuffer::ConvertToBuffer(IntRect* rect) const { - + } void WindowBuffer::ConvertToBuffer(BRegion* region) const { - + } void WindowBuffer::ConvertFromBuffer(BRect* rect) const { - + } void WindowBuffer::ConvertFromBuffer(BPoint* point) const { - + } void WindowBuffer::ConvertFromBuffer(IntRect* rect) const { - + } void WindowBuffer::ConvertFromBuffer(BRegion* region) const { - + } @@ -170,13 +184,15 @@ WindowBuffer::Bits() const if (fBuffer != NULL) return fBuffer; - else + else { + CAPTRACE("allocate buffer\n"); fBuffer = malloc(BytesPerRow() * fHeight); + } // TODO: fail more nicely? Maybe trigger memory cleanup? if (fBuffer == NULL) debugger("WindowBuffer malloc() failed\n"); - + return fBuffer; } @@ -211,7 +227,7 @@ WindowBuffer::Height() const // #pragma mark - - +// TODO: move to WeakLazyLocker bool WindowBuffer::ClientDrawLock() { @@ -234,7 +250,7 @@ WindowBuffer::CopyToFrontLock() if (fLock.Lock() && fClientDrawLock.Lock()) return true; _LOG("FAILURE!\nFAILURE!!\tWindowBuffer::CopyToFrontLock()\nFAILURE!\n"); - return false; + return false; } @@ -249,7 +265,7 @@ WindowBuffer::CopyToFrontUnlock() /*! Internal Resizing. Resizes buffer to exact size given. - * + * * This is a heavy-handed function, allocating new memory, copying the old data * into the new memory line by line - currently without any acceleration. */ @@ -270,7 +286,7 @@ WindowBuffer::_ResizeTo(int32 width, int32 height) if (fBuffer != NULL) { uint32 bytesPerPixel = 4; - uint32 bytesPerRow = bytesPerPixel*width; + uint32 bytesPerRow = BPrivate::get_bytes_per_row(B_RGBA32, width); uint32* destBuffer = (uint32*)malloc(bytesPerRow*height); uint32* newBuffer = destBuffer; uint32* srcBuffer = (uint32*)fBuffer; @@ -354,11 +370,10 @@ WindowBuffer::_ResizeTo(int32 width, int32 height) bool WindowBuffer::_NewWindowSize(int32* width, int32* height) { - // TODO: make aware of app_server settings: - // compositing enabled, decor buffering, shadows enabled + // TODO: // A mechanism to individually inform the WindowBuffer that a decorator // or shadow will be drawing into it - in addition to its offsets... - + // sanity checks if (*width < 0) *width = 0; if (*height < 0) *height = 0; @@ -368,7 +383,7 @@ WindowBuffer::_NewWindowSize(int32* width, int32* height) fBounds.left = 0; fBounds.top = 0; - + fBounds.right = newW - 1; fBounds.bottom = newH - 1; diff --git a/src/servers/app/drawing/WindowBuffer.h b/src/servers/app/drawing/WindowBuffer.h index 1066812..2dd20ff 100644 --- a/src/servers/app/drawing/WindowBuffer.h +++ b/src/servers/app/drawing/WindowBuffer.h @@ -18,13 +18,14 @@ class WindowBuffer : public RenderingBuffer{ // New Window size. void ResizeTo(int32 width, int32 height); + void ResizeBy(int32 x, int32 y); // coordinate space conversion to/from Window void ConvertToBuffer(BRect* rect) const; void ConvertToBuffer(BPoint* point) const; void ConvertToBuffer(IntRect* rect) const; void ConvertToBuffer(BRegion* region) const; - + void ConvertFromBuffer(BRect* rect) const; void ConvertFromBuffer(BPoint* point) const; void ConvertFromBuffer(IntRect* rect) const; @@ -50,7 +51,7 @@ class WindowBuffer : public RenderingBuffer{ // Lock for client drawing bool ClientDrawLock(); void ClientDrawUnlock(); - + bool CopyToFrontLock(); void CopyToFrontUnlock(); diff --git a/src/servers/app/drawing/interface/local/CompositeEngine.cpp b/src/servers/app/drawing/interface/local/CompositeEngine.cpp index 88504a2..c58f721 100644 --- a/src/servers/app/drawing/interface/local/CompositeEngine.cpp +++ b/src/servers/app/drawing/interface/local/CompositeEngine.cpp @@ -58,9 +58,6 @@ CompositeEngineClient::~CompositeEngineClient() void CompositeEngineClient::SetCompositeEngine(CompositeEngine* engine) { - _LOGF("CompositeEngineClient (%p) SetEngine from (%p) to (%p)\n", - this, fCompositeEngine, engine); - if (fCompositeEngine != NULL) fCompositeEngine->Detach(this); diff --git a/src/servers/app/drawing/interface/local/CompositeWindow.cpp b/src/servers/app/drawing/interface/local/CompositeWindow.cpp index 4008e3f..3cf75dc 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindow.cpp +++ b/src/servers/app/drawing/interface/local/CompositeWindow.cpp @@ -12,6 +12,7 @@ #include "CompositeEngine.h" #include "CompositeWindowHWInterface.h" #include "CompositeWindow.h" +#include "DrawingEngine.h" #include "Window.h" #include "WindowBuffer.h" @@ -22,24 +23,41 @@ CompositeWindow::CompositeWindow(BRect frame, const char* name, window_look look, window_feel feel, uint32 flags, uint32 wspaces, ::ServerWindow* window, HWInterface* hwInterface) - :Window(frame, name, look, feel, flags, wspaces, window, - hwInterface->CreateDrawingEngine()), + :Window(frame, name, look, feel, flags, wspaces, window, NULL), CompositeEngineClient(_CompositeEngine()), fGraphicsCard(hwInterface), fIsCompositeWindow(_CompositeEngine() != NULL ? _CompositeEngine()->IsEnabled() : false) { - if (_CompositeHWInterface() != NULL) - _CompositeHWInterface()->SetWindow(this); + if (_CompositeWindowHWInterface() != NULL) + _CompositeWindowHWInterface()->SetWindow(this); + + fDrawingEngine = fGraphicsCard->CreateDrawingEngine(); + /* + TODO: + fDecoratorDrawingEngine needs to be a special engine + for the decorator to permit alpha blending. + + For now, we just use the AccelerantHWInterface to create + DrawingEngines for decorators. + */ + fDecoratorDrawingEngine = fDesktop->HWInterface() + ->CreateDrawingEngine(); + /* + TODO: + We need to look out for a few flags regarding if we accept + compositing or buffering at all. + + */ } CompositeWindow::~CompositeWindow() { - if (_CompositeHWInterface()) { - _CompositeHWInterface()->Shutdown(); - delete _CompositeHWInterface(); + if (_CompositeWindowHWInterface()) { + _CompositeWindowHWInterface()->Shutdown(); + delete _CompositeWindowHWInterface(); } } @@ -51,27 +69,24 @@ CompositeWindow::IsCompositeWindow() const } -bool -CompositeWindow::SetWindowBufferEnabled(bool enable) -{ - CAPTRACEF("%s\n", enable ? "TRUE" : "FALSE"); - // TODO!!! - return false; -} - - -bool -CompositeWindow::IsWindowBufferEnabled() const -{ - // TODO!!! - return false; -} - - void CompositeWindow::BeginUpdate(BPrivate::PortLink& link) { // Lock window buffer + if (IsCompositeWindow()) { + if (fGraphicsCard->IsDoubleBuffered()) { + /* + TODO: - prevent draw tearing + fGraphicsCard->SetCopyToFrontEnabled(false); + -- implement in CompositeWindowHWInterface + */ + } else + fLazyLock.ClientLock(); + } // locking is safe since our buffer state can't change + // until after the update, and the compositer will skip + // areas where it can't grab the server lock and catch + // out updates on the next frame. + Window::BeginUpdate(link); } @@ -82,6 +97,49 @@ CompositeWindow::EndUpdate() Window::EndUpdate(); // unlock window buffer // notify composite engine + + /* + TODO: + Shouldn't we consider accumulating the modified region(s) so the + window thread does it instead of the compositer control thread? + + Yeah, totally... but how to handle when lines are drawn? + They don't have a bounding box returned by painter, so we won't + know where the update has occurred accurately enough to not + repaint the entire bounding rect (which we can refactor Painter to + return). + + Ostensibly just capturing on the HWInterface's CopyBackToFront() + method and building a region from those calls should work, but I + believe there are known problems with double buffering in this + area, so I will need to investigate this. + + (Also for Julian Harnath's needs for BView layer system) + */ + + if (IsCompositeWindow()) { + if (fGraphicsCard->IsDoubleBuffered()) { + /* + TODO: + fGraphicsCard->SetCopyToFrontEnabled(true); + */ + } else + fLazyLock.ClientUnlock(); + } + + // TODO: + /* + We have two models to choose from, either the windows can create tasks + directly, or the composite control thread can iterate through the + windows. Due to the way Desktop handles its window list, it is nicely + sorted from back to front. Iterating through the list should very well + be faster than sorting a list of dirty windows or keeping the list of + dirty windows sorted - at least in the nominal case. + + And the idea is keeping the work out of the compositing time period, + such that the only things that happen are copies of buffers and alpha + blending (and possibly the next step in an effect, of course). + */ } @@ -153,6 +211,8 @@ CompositeWindow::RedrawDirtyRegion() //TODO: // Do we need to offset the region?? + // What coordinate space is this ? + // Screen or window? ProcessDirtyRegion(fDirtyRegion); @@ -187,8 +247,10 @@ void CompositeWindow::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion, bool resizeStack) { - if (_CompositeHWInterface() != NULL) - _CompositeHWInterface()->ResizeBy(x, y); + WLAutoClientLock _(&fLazyLock); + + if (_CompositeWindowHWInterface() != NULL) + _CompositeWindowHWInterface()->ResizeBy(x, y); Window::ResizeBy(x, y, dirtyRegion, resizeStack); } @@ -198,6 +260,7 @@ void CompositeWindow::SetFlags(uint32 flags, BRegion* updateRegion) { Window::SetFlags(flags, updateRegion); + /* We will be adding some flags. Some candidates: @@ -281,6 +344,7 @@ void CompositeWindow::CompositingEnabled(bool enabled) { CAPTRACEF("%s\n", enabled ? "ENABLED" : "DISABLED"); + WLAutoClientLock _(&fLazyLock); // the whole Desktop window list is compositing (by default) // ... or not... // Before this is called, we can't assume that to be the case, so this is @@ -297,8 +361,25 @@ void CompositeWindow::CompositingEnabling() { CAPTRACE("\n"); - //fIsCompositeWindow = true; - // allocate our buffers, set enabled, trigger client redraw + WLAutoClientLock _(&fLazyLock); + + fDrawingEngine->LockExclusiveAccess(); + if (_CompositeWindowHWInterface() == NULL) { + fGraphicsCard = new(std::nothrow) CompositeWindowHWInterface(fDesktop); + if (_CompositeWindowHWInterface() != NULL) { + _CompositeWindowHWInterface()->Initialize(); + _CompositeWindowHWInterface()->SetWindow(this); + + fDrawingEngine->SetHWInterface(fGraphicsCard); + + } else { + CAPTRACE("UNABLE TO CREATE CompositeWindowHWInterface!!\n"); + return; + } + } + fDrawingEngine->UnlockExclusiveAccess(); + + fIsCompositeWindow = (_CompositeWindowHWInterface() != NULL); } @@ -306,8 +387,38 @@ void CompositeWindow::CompositingDisabling() { CAPTRACE("\n"); - //fIsCompositeWindow = false; - // delete our buffers, trigger client redraw + fLazyLock.ClientLock(); + fDrawingEngine->LockExclusiveAccess(); + + if (_CompositeWindowHWInterface() != NULL) { + _CompositeWindowHWInterface()->Shutdown(); + delete fGraphicsCard; + fGraphicsCard = NULL; + + if (fDesktop != NULL) + fGraphicsCard = fDesktop->HWInterface(); + else { + CAPTRACE("NULL DESKTOP, WE'RE BONED!\n"); + } + } + + bool wasEnabled = fIsCompositeWindow; + fDrawingEngine->SetHWInterface(fGraphicsCard); + fDrawingEngine->UnlockExclusiveAccess(); + fIsCompositeWindow = false; + fLazyLock.ClientUnlock(); + + // Trigger full client redraw + if (wasEnabled) { + // TODO: + // ensure this doesn't result in double-draws + // it shouldn't, but we may, instead, want to + // clear the dirty region rather than having it + // include the visible region + fDirtyRegion.Include(&VisibleRegion()); + fDirtyCause |= UPDATE_REQUEST; + fDesktop->MarkDirty(fDirtyRegion); + } } @@ -493,19 +604,9 @@ CompositeWindow::_CompositeEngine() ::WindowBuffer* CompositeWindow::_WindowBuffer() { - if (fIsBufferedWindow - && fSecondaryWindowBuffer != NULL) - return fSecondaryWindowBuffer; - ::WindowBuffer* buffer = dynamic_cast<WindowBuffer*>(fGraphicsCard->DrawingBuffer()); -# if ENABLE_LOGGING - if (buffer == NULL) - _LOGF("ERROR: HWInterface (%p) for CompositeWindow (%p) has" - " non-WindowBuffer buffer!\n", fGraphicsCard, this); -# endif - return buffer; } @@ -513,25 +614,15 @@ CompositeWindow::_WindowBuffer() const ::WindowBuffer* CompositeWindow::_WindowBuffer() const { - if (fIsBufferedWindow - && fSecondaryWindowBuffer != NULL) - return fSecondaryWindowBuffer; - ::WindowBuffer* buffer = dynamic_cast<WindowBuffer*>(fGraphicsCard->DrawingBuffer()); -# if ENABLE_LOGGING - if (buffer == NULL) - _LOGF("ERROR: HWInterface (%p) for CompositeWindow (%p) has" - " non-WindowBuffer buffer!\n", fGraphicsCard, this); -# endif - return buffer; } CompositeWindowHWInterface* -CompositeWindow::_CompositeHWInterface() +CompositeWindow::_CompositeWindowHWInterface() { return dynamic_cast<CompositeWindowHWInterface*>(fGraphicsCard); } diff --git a/src/servers/app/drawing/interface/local/CompositeWindow.h b/src/servers/app/drawing/interface/local/CompositeWindow.h index 2d85141..72ba041 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindow.h +++ b/src/servers/app/drawing/interface/local/CompositeWindow.h @@ -30,10 +30,6 @@ public: virtual bool IsCompositeWindow() const; - // Render to self-managed WindowBuffer - bool SetWindowBufferEnabled(bool); - bool IsWindowBufferEnabled() const; - virtual void BeginUpdate(BPrivate::PortLink& link); virtual void EndUpdate(); @@ -61,6 +57,10 @@ public: bool ClientLock(); void ClientUnlock(); + // TODO: consider augmenting and exposing + // Window::UpdateSession for the CompositeEngine + //BRegion& GetUpdateSessionRegion(); + protected: // CompositeEngineClient stuff virtual void CompositingEnabled(bool); @@ -85,16 +85,13 @@ protected: private: ::CompositeEngine* _CompositeEngine(); - CompositeWindowHWInterface* _CompositeHWInterface(); + CompositeWindowHWInterface* _CompositeWindowHWInterface(); ::WindowBuffer* _WindowBuffer(); const ::WindowBuffer* _WindowBuffer() const; HWInterface* fGraphicsCard; bool fIsCompositeWindow; - bool fIsBufferedWindow; - - ::WindowBuffer* fSecondaryWindowBuffer; BRegion fDirtyAlphaRegion; BRegion fDirtyCopyRegion; diff --git a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp index 321e4d6..944a5f4 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp +++ b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp @@ -20,7 +20,8 @@ CompositeWindowHWInterface::CompositeWindowHWInterface(Desktop* desktop) : HWInterface(), fWindow(NULL), - fDesktop(desktop) + fDesktop(desktop), + fCopyToFrontNest(0) { } @@ -37,7 +38,40 @@ CompositeWindowHWInterface::SetWindow(CompositeWindow* window) { CAPTRACEF("from (%p) to (%p)\n", fWindow, window); - //TODO: test that they belong to fDesktop? + /* + TODO: + talk to compositing window accelerant for buffer + creation and deletion. + + if (_HasHardwareBuffers()) { + fACCDeleteBuffer(fFrontBuffer); + fACCDeleteBuffer(fBackBufferBuffer); + fFrontBuffer = fACCCreateBuffer(window->Frame()); + + if (IsDoubleBuffered()) + fBackBuffer = fACCCreateBuffer(window->Frame()); + } + + What I don't know how to handle is ensuring there is room for the + decorator or shadows, but I think with hardware support shadows would + not be rendered into the same buffer, and possibly also not the + decorator. + + This, sadly, means there may be some additional refactoring when + hardware buffers are used rather than relying on system memory. + + Then again, hUMA may just make that a moot point, we could just wait + for technology to catch up ;-) + */ + + delete fFrontBuffer; + delete fBackBuffer; + + fFrontBuffer = new(std::nothrow) WindowBuffer(window); + + if (IsDoubleBuffered()) + fBackBuffer = new(std::nothrow) WindowBuffer(window); + } @@ -83,20 +117,45 @@ CompositeWindowHWInterface::AvailableHWAcceleration() const void CompositeWindowHWInterface::ResizeBy(int32 x, int32 y) { - /* TODO! - if (_HasHardwareBuffers()) - fACCResizeBuffers(x, y); - else { +// if (_HasHardwareBuffers()) +// fACCResizeBuffers(x, y); +// else { if (fBackBuffer != NULL) fBackBuffer->ResizeBy(x, y); if (fFrontBuffer != NULL) fFrontBuffer->ResizeBy(x, y); +// } +} + + +status_t +CompositeWindowHWInterface::CopyBackToFront(const BRect& frame) +{ + if (fCopyToFrontNest != 0) { + fCopyToFrontRegion.Include(frame); + return B_OK; + } + + return HWInterface::CopyBackToFront(frame); +} + + +void +CompositeWindowHWInterface::SetCopyToFrontEnabled(bool enable) +{ + if (enable) { + atomic_add(&fCopyToFrontNest, -1); + if (fCopyToFrontNest == 0) { + _CopyBackToFront(fCopyToFrontRegion); + fCopyToFrontRegion.MakeEmpty(); } - */ + } else + atomic_add(&fCopyToFrontNest, 1); } + RenderingBuffer* CompositeWindowHWInterface::FrontBuffer() const { diff --git a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.h b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.h index 7a4ad9d..93696f5 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.h +++ b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.h @@ -24,8 +24,8 @@ class CompositeWindow; class CompositeWindowHWInterface : public HWInterface { public: - CompositeWindowHWInterface (Desktop* desktop); - virtual ~CompositeWindowHWInterface (); + CompositeWindowHWInterface(Desktop* desktop); + virtual ~CompositeWindowHWInterface(); void SetWindow(CompositeWindow*); @@ -38,6 +38,9 @@ public: virtual void ResizeBy(int32 x, int32 y); + virtual status_t CopyBackToFront(const BRect& frame); + void SetCopyToFrontEnabled(bool enable); + protected: // Access the proper buffer via DrawingBuffer() virtual RenderingBuffer* FrontBuffer() const; @@ -49,6 +52,8 @@ private: WindowBuffer* fFrontBuffer; WindowBuffer* fBackBuffer; + int32 fCopyToFrontNest; + BRegion fCopyToFrontRegion; public: /* A lot of stuff we don't care about... ############################################################################ Commit: 70f5d8fd08ae5b241a14129ad4b4b670e624dbfe Author: looncraz <looncraz@xxxxxxxxxxxx> Date: Thu Mar 26 19:34:16 2015 UTC Initialized buffers to NULL ---------------------------------------------------------------------------- diff --git a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp index 944a5f4..4b69ea0 100644 --- a/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp +++ b/src/servers/app/drawing/interface/local/CompositeWindowHWInterface.cpp @@ -21,6 +21,8 @@ CompositeWindowHWInterface::CompositeWindowHWInterface(Desktop* desktop) HWInterface(), fWindow(NULL), fDesktop(desktop), + fFrontBuffer(NULL), + fBackBuffer(NULL), fCopyToFrontNest(0) { }