added 1 changeset to branch 'refs/remotes/looncraz-github/CAP-volatile' old head: 9a6145e94f3f2ede998299f7635db0b75d8fcaa2 new head: 19a4ceb1deac3b5fdf5de1f6cb76b1c5a11be4ba ---------------------------------------------------------------------------- 19a4ceb: Window-level draw buffering. Introduce resizable WindowBuffer, give DrawingEngine ability to change buffers at run-time, give Painter ability to paint a RenderBuffer directly, add user API flag to selectively override window buffering. Compiles. No further testing performed. Window currently does not attempt to use WindowBuffer. [ Yourself <user@shredder.(none)> ] ---------------------------------------------------------------------------- Commit: 19a4ceb1deac3b5fdf5de1f6cb76b1c5a11be4ba Author: Yourself <user@shredder.(none)> Date: Tue Nov 6 22:41:16 2012 UTC ---------------------------------------------------------------------------- 10 files changed, 619 insertions(+), 6 deletions(-) headers/os/interface/Window.h | 3 +- src/servers/app/Window.cpp | 3 +- src/servers/app/Window.h | 10 + src/servers/app/drawing/DrawingEngine.cpp | 52 ++- src/servers/app/drawing/DrawingEngine.h | 9 +- src/servers/app/drawing/Jamfile | 2 + src/servers/app/drawing/Painter/Painter.cpp | 37 ++- src/servers/app/drawing/Painter/Painter.h | 3 + src/servers/app/drawing/WindowBuffer.cpp | 419 ++++++++++++++++++++++++ src/servers/app/drawing/WindowBuffer.h | 87 +++++ ---------------------------------------------------------------------------- diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index f1c406f..2acf631 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -77,7 +77,8 @@ enum { B_SAME_POSITION_IN_ALL_WORKSPACES = 0x00200000, B_AUTO_UPDATE_SIZE_LIMITS = 0x00400000, B_CLOSE_ON_ESCAPE = 0x00800000, - B_NO_SERVER_SIDE_WINDOW_MODIFIERS = 0x00000200 + B_NO_SERVER_SIDE_WINDOW_MODIFIERS = 0x00000200, + B_NO_BUFFERED_DRAWING = 0x01000000 }; #define B_CURRENT_WORKSPACE 0 diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 117e67a..26d2a65 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -119,7 +119,8 @@ Window::Window(const BRect& frame, const char *name, fMinHeight(1), fMaxHeight(32768), - fWorkspacesViewCount(0) + fWorkspacesViewCount(0), + fWindowBuffer(NULL) { _InitWindowStack(); diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h index 6817df2..73a365a 100644 --- a/src/servers/app/Window.h +++ b/src/servers/app/Window.h @@ -72,6 +72,7 @@ class DrawingEngine; class EventDispatcher; class Screen; class WindowBehaviour; +class WindowBuffer; class WorkspacesView; // TODO: move this into a proper place @@ -106,6 +107,13 @@ public: ::ServerWindow* ServerWindow() const { return fWindow; } ::EventTarget& EventTarget() const { return fWindow->EventTarget(); } + ::WindowBuffer* WindowBuffer() const + { return fWindowBuffer; } + + bool SetBufferEnabled(bool bufferEnabled); + + bool IsBufferEnabled() const + { return WindowBuffer() != NULL; } bool ReloadDecor(); @@ -431,6 +439,8 @@ protected: int32 fWorkspacesViewCount; + ::WindowBuffer* fWindowBuffer; + friend class DecorManager; private: diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 4e3a836..223800d 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -20,6 +20,8 @@ #include "ServerBitmap.h" #include "ServerCursor.h" #include "RenderingBuffer.h" +#include "Window.h" +#include "WindowBuffer.h" #include "drawing_support.h" @@ -101,6 +103,7 @@ DrawingEngine::DrawingEngine(HWInterface* interface) : fPainter(new Painter()), fGraphicsCard(NULL), + fDrawingBuffer(NULL), fAvailableHWAccleration(0), fSuspendSyncLevel(0), fCopyToFront(true) @@ -178,7 +181,15 @@ DrawingEngine::FrameBufferChanged() // NOTE: locking is probably bogus, since we are called // in the thread that changed the frame buffer... if (LockExclusiveAccess()) { - fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); + fPainter->DetachFromBuffer(); + + if (fDrawingBuffer != NULL){ + fPainter->AttachToBuffer(fDrawingBuffer); + } + else{ + fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); + } + // available HW acceleration might have changed fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration(); UnlockExclusiveAccess(); @@ -205,6 +216,18 @@ DrawingEngine::SetHWInterface(HWInterface* interface) void +DrawingEngine::SetDrawingBuffer(RenderingBuffer* buffer) +{ + if (LockExclusiveAccess()){ + fDrawingBuffer = buffer; + + FrameBufferChanged(); + UnlockExclusiveAccess(); + } +} + + +void DrawingEngine::SetCopyToFrontEnabled(bool enable) { fCopyToFront = enable; @@ -605,6 +628,7 @@ DrawingEngine::DrawBitmap(ServerBitmap* bitmap, const BRect& bitmapRect, { ASSERT_PARALLEL_LOCKED(); + BRect clipped = fPainter->ClipRect(viewRect); if (clipped.IsValid()) { AutoFloatingOverlaysHider _(fGraphicsCard, clipped); @@ -617,6 +641,24 @@ DrawingEngine::DrawBitmap(ServerBitmap* bitmap, const BRect& bitmapRect, void +DrawingEngine::DrawBuffer(RenderingBuffer* buffer, const BRect& bufferRect, + const BRect& viewRect, uint32 options) +{ + ASSERT_PARALLEL_LOCKED(); + + + BRect clipped = fPainter->ClipRect(viewRect); + if (clipped.IsValid()) { + AutoFloatingOverlaysHider _(fGraphicsCard, clipped); + + fPainter->DrawBuffer(buffer, bufferRect, viewRect, options); + + _CopyToFront(clipped); + } +} + + +void DrawingEngine::DrawArc(BRect r, const float& angle, const float& span, bool filled) { @@ -889,6 +931,7 @@ DrawingEngine::FillRegion(BRegion& r, const rgb_color& color) { ASSERT_PARALLEL_LOCKED(); + // NOTE: region expected to be already clipped correctly!! BRect frame = r.Frame(); if (!fPainter->Bounds().Contains(frame)) { @@ -1004,6 +1047,7 @@ DrawingEngine::FillRect(BRect r, const BGradient& gradient) ASSERT_PARALLEL_LOCKED(); make_rect_valid(r); + r = fPainter->AlignAndClipRect(r); if (!r.IsValid()) return; @@ -1373,7 +1417,6 @@ DrawingEngine::DrawString(const char* string, int32 length, const BPoint* offsets) { ASSERT_PARALLEL_LOCKED(); - // use a FontCacheRefernece to speed up the second pass of // drawing the string FontCacheReference cacheReference; @@ -1492,6 +1535,7 @@ BRect DrawingEngine::CopyRect(BRect src, int32 xOffset, int32 yOffset) const { // TODO: assumes drawing buffer is 32 bits (which it currently always is) + BRect dst; RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer(); if (buffer) { @@ -1533,6 +1577,7 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, uint32 bytesPerRow, int32 xOffset, int32 yOffset) const { // TODO: assumes drawing buffer is 32 bits (which it currently always is) + int32 xIncrement; int32 yIncrement; @@ -1597,3 +1642,6 @@ DrawingEngine::_CopyToFront(const BRect& frame) if (fCopyToFront) fGraphicsCard->Invalidate(frame); } + + + diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index ce89487..804cc50 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -20,13 +20,13 @@ #include "HWInterface.h" - class BPoint; class BRect; class BRegion; class DrawState; class Painter; +class RenderingBuffer; class ServerBitmap; class ServerCursor; class ServerFont; @@ -42,6 +42,8 @@ public: // for "changing" hardware void SetHWInterface(HWInterface* interface); + + void SetDrawingBuffer(RenderingBuffer*); virtual void SetCopyToFrontEnabled(bool enable); bool CopyToFrontEnabled() const @@ -97,6 +99,10 @@ public: virtual void DrawBitmap(ServerBitmap* bitmap, const BRect& bitmapRect, const BRect& viewRect, uint32 options = 0); + + virtual void DrawBuffer(RenderingBuffer* buffer, + const BRect& bufferRect, const BRect& viewRect, + uint32 options = 0); // drawing primitives virtual void DrawArc(BRect r, const float& angle, const float& span, bool filled); @@ -195,6 +201,7 @@ private: Painter* fPainter; HWInterface* fGraphicsCard; + RenderingBuffer*fDrawingBuffer; uint32 fAvailableHWAccleration; int32 fSuspendSyncLevel; bool fCopyToFront; diff --git a/src/servers/app/drawing/Jamfile b/src/servers/app/drawing/Jamfile index ff28d23..5c75fc1 100644 --- a/src/servers/app/drawing/Jamfile +++ b/src/servers/app/drawing/Jamfile @@ -29,6 +29,8 @@ StaticLibrary libasdrawing.a : BitmapHWInterface.cpp BBitmapBuffer.cpp HWInterface.cpp + + WindowBuffer.cpp ; SubInclude HAIKU_TOP src servers app drawing Painter ; diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 2dc6bb8..ff7b59b 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -1629,6 +1629,41 @@ Painter::DrawBitmap(const ServerBitmap* bitmap, BRect bitmapRect, } + +BRect +Painter::DrawBuffer(const RenderingBuffer* buffer, BRect srcRect, BRect destRect, + uint32 options) const +{ + CHECK_CLIPPING + + BRect touched = _Clipped(destRect); + + if (buffer && buffer->InitCheck() == B_OK && touched.IsValid()) { + // the native buffer coordinate system + BRect actualSourceRect(0, 0, buffer->Width()-1, buffer->Height()-1); + + TRACE("Painter::DrawBuffer()\n"); + TRACE(" actualSourceRect = (%.1f, %.1f) - (%.1f, %.1f)\n", + actualSourceRect.left, actualSourceRect.top, + actualSourceRect.right, actualSourceRect.bottom); + TRACE(" srcRect = (%.1f, %.1f) - (%.1f, %.1f)\n", + srcRect.left, srcRect.top, srcRect.right, + srcRect.bottom); + TRACE(" destRect = (%.1f, %.1f) - (%.1f, %.1f)\n", + destRect.left, destRect.top, destRect.right, destRect.bottom); + + agg::rendering_buffer srcBuffer; + srcBuffer.attach((uint8*)buffer->Bits(), buffer->Width(), buffer->Height(), + buffer->BytesPerRow()); + + _DrawBitmap(srcBuffer, buffer->ColorSpace(), actualSourceRect, + srcRect, destRect, options); + } + + return touched; +} + + // #pragma mark - @@ -1719,7 +1754,7 @@ Painter::_Transform(const BPoint& point, bool centerOffset) const BRect Painter::_Clipped(const BRect& rect) const { - if (rect.IsValid()) + if (rect.IsValid() && fClippingRegion != NULL) return BRect(rect & fClippingRegion->Frame()); return BRect(rect); diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 645c95b..9b39684 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -220,6 +220,9 @@ public: BRect DrawBitmap(const ServerBitmap* bitmap, BRect bitmapRect, BRect viewRect, uint32 options) const; + + BRect DrawBuffer(const RenderingBuffer* buffer, + BRect src, BRect dest, uint32 options) const; // some convenience stuff BRect FillRegion(const BRegion* region) const; diff --git a/src/servers/app/drawing/WindowBuffer.cpp b/src/servers/app/drawing/WindowBuffer.cpp new file mode 100644 index 0000000..f5adf3a --- /dev/null +++ b/src/servers/app/drawing/WindowBuffer.cpp @@ -0,0 +1,419 @@ +/* + * Copyright 2001-2009, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Joseph Groover <looncraz@xxxxxxxxxxx> + */ + + +#include <Autolock.h> +#include <malloc.h> +#include <InterfacePrivate.h> +#include <Screen.h> +#include <syslog.h> + +#include <Window.h> + +#include "Window.h" + +#include "DrawingEngine.h" +#include "drawing_support.h" +#include "WindowBuffer.h" + +//#include "RapidDebug.h" + +#define _LOGF(...) + +WindowBuffer::WindowBuffer(Window* window) + : + RenderingBuffer(), + fWidth((int32)window->Frame().Width()), + fHeight((int32)window->Frame().Height()), + fBufferFillPattern(4294967295LL), + fBufferFillSrc(NULL), + fOverProvision(30), + fBounds(window->Frame()), + fWindow(window), + fBuffer(NULL) +{ + fBounds.OffsetBy(-fBounds.left, -fBounds.top); + +# if ENABLE_LOGGING + BRect rect = window->Frame(); + + _LOGF("WindowBuffer(%s)( %i, %i, %i, %i )\n", + window->Title(), + (int)rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom + ); + +# endif + + _NewWindowSize(&fWidth, &fHeight); + + + SetBufferFillPattern(0); + FillBuffer(); + _LOGF("\tBuffer created: %li x %li\n", fWidth, fHeight); +} + +// destructor +WindowBuffer::~WindowBuffer() +{ + fLock.Lock(); + + if (fBufferFillSrc != NULL) + free(fBufferFillSrc); + if (fBuffer != NULL) + free(fBuffer); +} + + +// #pragma mark resizing + + +void // see _ResizeTo() && _NewWindowSize() +WindowBuffer::ResizeTo(int32 width, int32 height) +{ + BAutolock _(fLock); + int32 newW = width, newH = height; + + if (_NewWindowSize(&newW, &newH)) + _ResizeTo(newW, newH); + +} + + +void +WindowBuffer::ResizeBy(int32 horizontal, int32 vertical) +{ + ResizeTo(fBounds.Width() + horizontal, + fBounds.Height() + vertical); +} + +// #prgma mark - + +bool +WindowBuffer::Lock() +{ + return fLock.Lock(); +} + +void +WindowBuffer::Unlock() +{ + fLock.Unlock(); +} + + +Window* +WindowBuffer::GetWindow() +{ + return fWindow; +} + + +// #pragma mark Mandatory + +status_t +WindowBuffer::InitCheck() const +{ + BAutolock _(fLock); + + if (fWidth > 0 && fHeight > 0) + return B_OK; + + return B_BAD_VALUE; +} + + +color_space +WindowBuffer::ColorSpace() const +{ + return B_RGBA32; +} + + +void* +WindowBuffer::Bits() const +{ BAutolock __(fLock); + + if (fBuffer != NULL){ + // if (!fIsCompressed) + return fBuffer; + //else{ + //_DecompressBuffer(); + //} + }else + fBuffer = malloc(BytesPerRow() * fHeight); + + + if (fWindow != NULL) + _LOGF("Bits() called: %s\n", fWindow->Title()); + + + return fBuffer; +} + + +uint32 +WindowBuffer::BytesPerRow() const +{ BAutolock _(fLock); + + // I am assuming this is equal to frame_buffer_config's bytes_per_row + // this is vital, I believe, for acceleration to work correctly. + + return BPrivate::get_bytes_per_row(B_RGBA32, fWidth); +} + + +uint32 +WindowBuffer::Width() const +{ BAutolock _(fLock); + if (fWidth < 0 ) + return 0; + return fWidth; +} + + +uint32 +WindowBuffer::Height() const +{ BAutolock _(fLock); + if (fHeight <0) + return 0; + return fHeight; +} + + +// #pragma mark - + + +void +WindowBuffer::FillBuffer() +{ + BAutolock _(fLock); + + uint32 * dest = (uint32*)Bits(); + + if (dest == NULL + || Width() == 0 + || Height() == 0) + return; + + uint32 bpr = BytesPerRow(); // cache it because it is "heavy" + + if (fBufferFillSrc == NULL){ + fBufferFillSrc = (uint32*)malloc(bpr); + for (uint32 i = 0; i < bpr/4; ++i) + fBufferFillSrc[i] = fBufferFillPattern; + } + + for (uint32 i = 0; i < Height(); ++i) { + gfxcpy32((uint8*)dest, (const uint8*)fBufferFillSrc, bpr); + dest += Width(); + } + +} + + +void +WindowBuffer::SetBufferFillColor(rgb_color color) +{ + SetBufferFillPattern(_ColorPattern(color)); +} + + +void +WindowBuffer::SetBufferFillPattern(uint32 pattern) +{ BAutolock _(fLock); + + fBufferFillPattern = pattern; + + if (fBufferFillSrc) + free(fBufferFillSrc); + + fBufferFillSrc = (uint32*)malloc(BytesPerRow()); + + if (fBufferFillSrc != NULL) + for (uint32 i = 0; i < BytesPerRow()/4; ++i) + fBufferFillSrc[i] = fBufferFillPattern; + // we DO NOT draw just because the color changed... +} + + +bool +WindowBuffer::LockForUpdate(bigtime_t scheduledUpdate) +{ +// if (fLastUpdate + fUpdateInterval < scheduledUpdate){ + fClientDrawLock.Lock(); + return Lock(); +// } + +// return false; +} + + +void +WindowBuffer::UnlockFromUpdate() +{ +// fLastUpdate = system_time(); + fClientDrawLock.Unlock(); + Unlock(); +} + + +// #pragma mark private + +uint32 +WindowBuffer::_ColorPattern(const rgb_color &color) +{ // NativeColor() may use the accelerant's features + + return (uint32)(color.alpha << 24) | (color.red << 16) | (color.green << 8) + |(color.blue); +// return gCompositeEngine->NativeColor(color); +} + + +/* + + This resize function refers to the resizing of the buffer + itself. +*/ + +void +WindowBuffer::_ResizeTo(int32 width, int32 height) +{ +/* + calls to here come exclusively from the Desktop thread, so + we should already be locked and drawing should be suspended. +*/ + _LOGF( + "_ResizeTo from (%lu, %lu) to (%lu, %lu)\n", + fWidth, fHeight, width, height + ); + + BAutolock _(fLock); + + if (width == fWidth && height == fHeight) + return; + + // todo: should we LockExclusiveAccess() to the drawing engine? + // it may be superfluous.. but maybe not... + + if (fBuffer != NULL){ + + uint32 bpp = 4, + bpr = bpp*width; + uint32* destBuffer = (uint32*)malloc(bpr*height), + *newBuffer = destBuffer; + uint32* srcBuffer = (uint32*)fBuffer; + + if (destBuffer == NULL){ + debugger("WindowBuffer::_ResizeTo():\n\t" + "Unable to allocate destination buffer\n"); + return; + } + + // all of these need to be created here, dont't fuss... + int32 srcWidth = fWidth, + srcLen = srcWidth*bpp, + destWidth = width, + destLen = destWidth*bpp, + srcHeight = fHeight, + xDelta = width - fWidth, + xDeltaLen = xDelta * bpp, + yDelta = height - fHeight, + xShrinkDelta= 0; + + // shrinking... + if (srcWidth > width){ + xShrinkDelta = srcWidth - width; + srcWidth = width; + srcLen = srcWidth * bpp; + xDelta = 0; + xDeltaLen = 0; + } + + if (srcHeight > height){ + srcHeight = height; + yDelta = 0; + } + + // copy the old data row-by-row to the new buffer + for (int32 y = 0; y < srcHeight; ++y){ + gfxcpy32((uint8*)destBuffer, (const uint8*)srcBuffer, srcLen); + destBuffer += srcWidth; + srcBuffer += srcWidth + xShrinkDelta; + if (xDelta){ // zero-fill extra width for drawing... + gfxset32((uint8*)destBuffer, 0, xDeltaLen); + destBuffer += xDelta; + } + } + + // zero-fill extra height for drawing + for (int32 y = 0; y < yDelta; ++y){ + gfxset32((uint8*)destBuffer, 0, destLen); + destBuffer += destWidth; + } + + fWidth = width; + fHeight = height; + + free(fBuffer); + fBuffer = newBuffer; + } // end buffer NULL-check + + fWidth = width; + fHeight = height; + + // as our pointer changed, the drawing engine needs to be updated: + fWindow->GetDrawingEngine()->SetDrawingBuffer(this); +} + + +// determine proper buffer size for a given window width & height +// we also determine the new windowFrame for convenience + +bool +WindowBuffer::_NewWindowSize(int32* width, int32* height) +{ + // sanity checks + if (*width < 0) *width = 0; + if (*height < 0) *height = 0; + + int32 newW = *width, + newH = *height; + + fBounds.left = 0; + fBounds.top = 0; + + fBounds.right = newW - 1; + fBounds.bottom = newH - 1; + + bool resizeBuffer = false; + + if (newW > fWidth){ + if ((fWindow->Flags() & B_NOT_RESIZABLE) == false + && (fWindow->Flags() & B_NOT_H_RESIZABLE) == false) + newW += fOverProvision; + + *width = newW; + resizeBuffer = true; + } + else + *width = fWidth; + + if (newH > fHeight){ + if ((fWindow->Flags() & B_NOT_RESIZABLE) == false + && (fWindow->Flags() & B_NOT_V_RESIZABLE) == false) + newH += fOverProvision; + + *height = newH; + resizeBuffer = true; + } + else + *height = fHeight; + + return resizeBuffer; +} + diff --git a/src/servers/app/drawing/WindowBuffer.h b/src/servers/app/drawing/WindowBuffer.h new file mode 100644 index 0000000..7e178a0 --- /dev/null +++ b/src/servers/app/drawing/WindowBuffer.h @@ -0,0 +1,87 @@ +/* + * Copyright 2001-2009, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Joseph Groover <looncraz@xxxxxxxxxxx> + */ + +#ifndef WINDOW_BUFFER_H +#define WINDOW_BUFFER_H + +#include <Locker.h> +#include <GraphicsDefs.h> +#include <Region.h> + +#include "RenderingBuffer.h" + +class Window; + +class WindowBuffer : public RenderingBuffer{ + public: + WindowBuffer(Window* window); + virtual ~WindowBuffer(); + + size_t MemoryUsage(); + + // resizes the WINDOW + void ResizeTo(int32 width, int32 height); + void ResizeBy(int32 horiz, int32 vert); + + // this locks the buffer during drawing or during + // screen refresh + + bool Lock(); + void Unlock(); + bool IsLocked(); + + Window* GetWindow(); + + // standard stuff for RenderingBuffer + virtual status_t InitCheck() const; + virtual color_space ColorSpace() const; + virtual void* Bits() const; + virtual uint32 BytesPerRow() const; + // the Width() and Height() are for the buffer, not the window! + virtual uint32 Width() const; + virtual uint32 Height() const; + + void FillBuffer(); + + void SetBufferFillColor(rgb_color); + void SetBufferFillPattern(uint32); + + size_t ReduceMemoryFootprint(bool max = false); + // shrinks window buffer to fit contents, if max is true + // we will also eleminate over-provisioning + // Returns memory saved by operation. + + // the update session, when client draws, we need to be locked. + // if we don't, we will get flickering/tearing. + bool LockForUpdate(bigtime_t = system_time()); + void UnlockFromUpdate(); + + private: + uint32 _ColorPattern(const rgb_color&); + void _ResizeTo(int32 width, int32 height); + bool _NewWindowSize(int32* width, int32* height); + + mutable BLocker fLock, + fClientDrawLock; + + int32 fWidth, + fHeight; + + uint32 fBufferFillPattern, + * fBufferFillSrc; + + uint8 fOverProvision; + + IntRect fBounds; + + Window* fWindow; + + mutable void* fBuffer; +}; + +#endif // WINDOW_BUFFER_H