[haiku-commits] BRANCH looncraz-github.CAP-dirty [835a04684937] in src: servers/app/drawing/interface/local servers/app servers/app/drawing bin/capset

  • From: looncraz-github.CAP-dirty <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 11 Jul 2015 03:46:51 +0200 (CEST)

added 20 changesets to branch 'refs/remotes/looncraz-github/CAP-dirty'
old head: ec1d81976ab2c559f67dab001165546d54288809
new head: 835a04684937d84889019ff8334738d784f015ca
overview: https://github.com/looncraz/haiku/compare/ec1d81976ab2...835a04684937

----------------------------------------------------------------------------

70b0678a8206: Continue squashing commits

Minimal CAP

Begin CAP: Compositing for Appropriate Purposes

Removed compositing branch, created several new ones.
ReadMe explains it all.

cap.looncraz.net will, in the near future, will be home
to supporting documents and packages and will be the
proper forum for announcements and detailed planning.

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.

Trimming, some style corrections, prep-work for first buffered window.

RapidDebug included - to be removed before any patch submissions.

Initial painting of WindowBuffer to frame buffer and coordinate system
conversion methods.

This work compiles and works, however there are some trivial issues.
There are NO added benefits from buffering yet as client draws still
occur on each update.

Still only restricted to a single window for testing.

Continue fine-tuning offset optimization (View), more coordinate space
conversion work, remove some old cruft, some more style cleanup.

More clipping modifications (mostly complete), removal of some logging code,
etc.

Builds, runs, works.

Memory is leaking even though free() is called, need to prevent client
re-draws on exposes, need to modify redraw logic for resizing - maybe just a
clipping problem, but things don't look right. Also need to fill buffer with
parent view background color as there seems to be some trickery I'm
missing for view colors...

Minor style fixes, move coordinate conversion to right place, include Chart
for testing updates.

Still some off-by-one errors, and not all clipping is properly converted
(hard to find all these places as the app_server was designed with the idea
of painting directly to the screen in mind... Resizing is much better now.

Performance is significantly better than expected considering all of the
additional redrawing and region copying currently going on, but
optimizations are forthcoming.

Make drawing outside of BView::Draw(BRect) visible.

This is a partial commit while I examine the need for entirely new
clipping and drawing logic for all on-screen objects. Basically,
to strip out the logic from the middle of unrelated code to
facilitate future modifications to said behavior(s).

Current idea is to implement all of the following:

OnScreenPolicy
:ClippingPolicy
:DrawingPolicy

Desktop
:OnScreenPolicy

OnScreenObject
:ClippingObject
:DrawingObject

Window
:OnScreenObject

WindowBuffer
:OnScreenObject

Decorator
:OnScreenObject

WindowList->OnScreenList
window_anchor->onscreen_anchor

etc...

All current clipping and drawing code (relative to Window) will be
relocated and refactored in this experiment to centralize logic.

Update ReadMe

Get rid of some superfluous commentary

[ Yourself <user@shredder.(none)> ]

352ca7930278: Rebase remnants removal

[ looncraz <looncraz@xxxxxxxxxxxx> ]

12875a54fcf7: Style cleanup

(Thanks Axel!)

[ looncraz <looncraz@xxxxxxxxxxxx> ]

ede329f4214b: Place saver

Create dirty branch to make quick saves that are more volatile than
CAP-volatile...

yeah, seriously!

[ looncraz <looncraz@xxxxxxxxxxxx> ]

bc001f2cfbb2: Pick up some dirty stragglers

[ looncraz <looncraz@xxxxxxxxxxxx> ]

7acd54b0800b: Moving along

Properly separate Window and CompositeWindow, implement many little
bits in that regard to handle the difference between a dirtregion
and a region which genuinely needs to be redrawn by the client.

Included a WeakLazyLocker - completely untested, but similar to
something else I've used for quite some time, so it should be OK.
Hey, there's a reason I call this the 'dirty' branch!

[ looncraz <looncraz@xxxxxxxxxxxx> ]

2ba1a2d47019: Move coordinate conversions & complete renaming

OffscreenServerWindow had the coordinate conversion methods for
some reason, they belong in OffscreenWindow.

Also completed renaming ConvertViewToDrawing to ConvertWindowToDrawing,
which is more accurate.

[ looncraz <looncraz@xxxxxxxxxxxx> ]

422d08f0a6e8: WeakLazyLocker

Try to get the lock when it seems safe to do so in SetLazyServerLock()

[ looncraz <looncraz@xxxxxxxxxxxx> ]

e083c1752c75: Initial CompositeEngine (v2)

Now overloading AccelerantHWInterface and giving each window its own
CompositeWindowHWInterface which will need to interact with a dedicated
type of accelerant for client-draw acceleration.

Dozens of other small changes.

This is the dirty branch, this stuff is full of errors ;-)

[ looncraz <looncraz@xxxxxxxxxxxx> ]

1bdb582bbf29: Compiles, links

A great deal more fleshing out. Finally compiles and links, but the basic
control structure is still incomplete.

This part is working out smoothly, I should be able to bring in more
of the non-public code here and there as time progresses.

[ looncraz <looncraz@xxxxxxxxxxxx> ]

0f8b557184e3: Fix Cyclic Call

Don't you just hate it when you forget to reference the derive class's
version of a function call you overloaded and cause a KDL?

I sure do.

[ looncraz <looncraz@xxxxxxxxxxxx> ]

24f08db73adb: Style cleanup

[ looncraz <looncraz@xxxxxxxxxxxx> ]

7ec4cb13105d: Fix CompositeHWInterface

[ looncraz <looncraz@xxxxxxxxxxxx> ]

567469a8bb5c: Modify RapidDebug

[ looncraz <looncraz@xxxxxxxxxxxx> ]

ca18eeef551a: Client-Server Protocol

Define and implement basic interface for controlling compositing
on a live system.

Added in system bin 'capset' to provide command-line access to features
as well as for testing purposes.

More to go!

[ looncraz <looncraz@xxxxxxxxxxxx> ]

81ee88ec1a43: Initial Communications

Can now pull and set the state. Though, you seriously don't want
to enable compositing right now. Things, as expected, go a little
kooky.

[ looncraz <looncraz@xxxxxxxxxxxx> ]

76e43c469e69: Minor tweaks

Prevent CompositeWindow from setting itself to compositing mode for now,
Add a client auto-locker for WeakLazyLocker.
Fixed a race condition in WeakLazyLocker.
Minor update to set state handling

[ looncraz <looncraz@xxxxxxxxxxxx> ]

a3821005e613: 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()

[ looncraz <looncraz@xxxxxxxxxxxx> ]

f75cde3bbb27: Initialized buffers to NULL

[ looncraz <looncraz@xxxxxxxxxxxx> ]

835a04684937: Get rid of spurios locks

Access is mostly serialized and locking just adds overhead and the
potential for deadlocks, so getting rid of it wherever possible.

Also modified (temporarily) the bootscript to launch the app_server
from the root of the boot drive for testing.

Almost to the point where I can replace the app_server on the running
system and restart rather than runninbuilds on one virtual machine
and testing on another

[ looncraz <looncraz@xxxxxxxxxxxx> ]

----------------------------------------------------------------------------

46 files changed, 4104 insertions(+), 106 deletions(-)
build/jam/images/definitions/minimum | 2 +-
data/system/boot/Bootscript | 3 +-
headers/os/interface/Window.h | 3 +-
headers/private/app/ServerProtocol.h | 11 +
headers/private/app/ServerProtocolStructs.h | 19 +
src/bin/Jamfile | 1 +
src/bin/capset/Jamfile | 9 +
src/bin/capset/capset.cpp | 342 ++++++++++
src/servers/app/AppServer.cpp | 1 +
src/servers/app/Desktop.cpp | 208 +++++-
src/servers/app/Desktop.h | 8 +
src/servers/app/DesktopSettings.cpp | 54 ++
src/servers/app/DesktopSettings.h | 3 +
src/servers/app/DesktopSettingsPrivate.h | 7 +
src/servers/app/OffscreenServerWindow.h | 2 +-
src/servers/app/OffscreenWindow.h | 11 +
src/servers/app/ProfileMessageSupport.cpp | 12 +-
src/servers/app/RapidDebug.h | 46 ++
src/servers/app/ScreenManager.cpp | 6 +-
src/servers/app/ServerWindow.cpp | 125 ++--
src/servers/app/View.cpp | 395 ++++++++++-
src/servers/app/View.h | 34 +
src/servers/app/Window.cpp | 276 +++++++-
src/servers/app/Window.h | 62 +-
src/servers/app/decorator/DecorManager.cpp | 8 +-
src/servers/app/drawing/DrawingEngine.cpp | 48 +-
src/servers/app/drawing/DrawingEngine.h | 8 +
src/servers/app/drawing/Jamfile | 2 +
src/servers/app/drawing/Painter/Painter.cpp | 39 +-
src/servers/app/drawing/Painter/Painter.h | 3 +
.../drawing_modes/DrawingModeSelectSUBPIX.h | 2 +-
.../Painter/drawing_modes/PixelFormat.cpp | 4 +-
src/servers/app/drawing/WindowBuffer.cpp | 419 ++++++++++++
src/servers/app/drawing/WindowBuffer.h | 75 +++
.../drawing/interface/local/CompositeEngine.cpp | 359 ++++++++++
.../drawing/interface/local/CompositeEngine.h | 95 +++
.../interface/local/CompositeHWInterface.cpp | 115 ++++
.../interface/local/CompositeHWInterface.h | 44 ++
.../drawing/interface/local/CompositeWindow.cpp | 664 +++++++++++++++++++
.../drawing/interface/local/CompositeWindow.h | 104 +++
.../local/CompositeWindowHWInterface.cpp | 175 +++++
.../interface/local/CompositeWindowHWInterface.h | 105 +++
.../drawing/interface/local/CompositingDefs.h | 67 ++
src/servers/app/drawing/interface/local/Jamfile | 6 +
.../drawing/interface/local/WeakLazyLocker.cpp | 126 ++++
.../app/drawing/interface/local/WeakLazyLocker.h | 102 +++

############################################################################

Commit: 70b0678a8206db97a2a882ade5c932df362d7068
Author: Yourself <user@shredder.(none)>
Date: Mon Oct 29 03:47:05 2012 UTC
Committer: looncraz <looncraz@xxxxxxxxxxxx>
Commit-Date: Sat Jul 11 01:29:16 2015 UTC

Continue squashing commits

Minimal CAP

Begin CAP: Compositing for Appropriate Purposes

Removed compositing branch, created several new ones.
ReadMe explains it all.

cap.looncraz.net will, in the near future, will be home
to supporting documents and packages and will be the
proper forum for announcements and detailed planning.

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.

Trimming, some style corrections, prep-work for first buffered window.

RapidDebug included - to be removed before any patch submissions.

Initial painting of WindowBuffer to frame buffer and coordinate system
conversion methods.

This work compiles and works, however there are some trivial issues.
There are NO added benefits from buffering yet as client draws still
occur on each update.

Still only restricted to a single window for testing.

Continue fine-tuning offset optimization (View), more coordinate space
conversion work, remove some old cruft, some more style cleanup.

More clipping modifications (mostly complete), removal of some logging code,
etc.

Builds, runs, works.

Memory is leaking even though free() is called, need to prevent client re-draws
on exposes, need to modify redraw logic for resizing - maybe just a
clipping problem, but things don't look right. Also need to fill buffer with
parent view background color as there seems to be some trickery I'm
missing for view colors...

Minor style fixes, move coordinate conversion to right place, include Chart for
testing updates.

Still some off-by-one errors, and not all clipping is properly converted (hard
to find all these places as the app_server was designed with the idea
of painting directly to the screen in mind... Resizing is much better now.

Performance is significantly better than expected considering all of the
additional redrawing and region copying currently going on, but
optimizations are forthcoming.

Make drawing outside of BView::Draw(BRect) visible.

This is a partial commit while I examine the need for entirely new
clipping and drawing logic for all on-screen objects. Basically,
to strip out the logic from the middle of unrelated code to
facilitate future modifications to said behavior(s).

Current idea is to implement all of the following:

OnScreenPolicy
:ClippingPolicy
:DrawingPolicy

Desktop
:OnScreenPolicy

OnScreenObject
:ClippingObject
:DrawingObject

Window
:OnScreenObject

WindowBuffer
:OnScreenObject

Decorator
:OnScreenObject

WindowList->OnScreenList
window_anchor->onscreen_anchor

etc...

All current clipping and drawing code (relative to Window) will be
relocated and refactored in this experiment to centralize logic.

Update ReadMe

Get rid of some superfluous commentary

----------------------------------------------------------------------------

diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h
index b4df13e..493bfc5 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/AppServer.cpp b/src/servers/app/AppServer.cpp
index a17a9d0..19a55ac 100644
--- a/src/servers/app/AppServer.cpp
+++ b/src/servers/app/AppServer.cpp
@@ -39,6 +39,7 @@ static AppServer* sAppServer;
BTokenSpace gTokenSpace;
uint32 gAppServerSIMDFlags = 0;

+FILE* _ddfl = fopen("/boot/appserver-debug.txt", "w");

/*! \brief Constructor

diff --git a/src/servers/app/OffscreenServerWindow.h
b/src/servers/app/OffscreenServerWindow.h
index 34e3d52..224e4f3 100644
--- a/src/servers/app/OffscreenServerWindow.h
+++ b/src/servers/app/OffscreenServerWindow.h
@@ -28,6 +28,18 @@ public:
window_look look,
window_feel feel, uint32 flags,
uint32 workspace);

+ // override (and disable) Window coordinate space converions
+ virtual void ConvertViewToDrawing(BPoint* point)
const{}
+ virtual void ConvertViewToDrawing(BRect* rect)
const{}
+ virtual void ConvertViewToDrawing(BRegion* region)
const{}
+ virtual void ConvertViewToDrawing(IntRect* rect)
const{}
+
+ virtual void ConvertDrawingToWindow(BPoint* point)
const{}
+ virtual void ConvertDrawingToWindow(BRect* rect)
const{}
+ virtual void ConvertDrawingToWindow(BRegion* region)
const{}
+ virtual void ConvertDrawingToWindow(IntRect* rect)
const{}
+
+
private:
ServerBitmap* fBitmap;
};
diff --git a/src/servers/app/RapidDebug.h b/src/servers/app/RapidDebug.h
new file mode 100644
index 0000000..81631e1
--- /dev/null
+++ b/src/servers/app/RapidDebug.h
@@ -0,0 +1,35 @@
+#ifndef TEMP_RAPID_DEBUG_H
+#define TEMP_RAPID_DEBUG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <String.h>
+
+
+extern "C" FILE* _ddfl;
+
+#define ENABLE_LOGGING 1
+#define LOG_DRAWING 0
+
+#if ENABLE_LOGGING
+# define _LOG(X) fprintf(_ddfl, X); ::fflush(_ddfl);
+# define _LOGF(X, Y...) fprintf(_ddfl, X, Y); ::fflush(_ddfl);
+#else
+# define _LOG(X)
+# define _LOGF(X, Y...)
+#endif
+
+
+#if LOG_DRAWING
+# define _LOGDRAW(X) LOG(X)
+# define _LOGFDRAW(X, Y...) LOGF(X, Y)
+#else
+# define _LOGDRAW(X)
+# define _LOGFDRAW(X, Y...)
+#endif
+
+
+
+#endif // TEMP_RAPID_DEBUG_H
+
+
diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp
index 242438f..c9dd7d0 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -63,12 +63,14 @@
#include "HWInterface.h"
#include "Overlay.h"
#include "ProfileMessageSupport.h"
+#include "RapidDebug.h"
#include "RenderingBuffer.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
#include "ServerPicture.h"
#include "ServerProtocol.h"
#include "Window.h"
+#include "WindowBuffer.h"
#include "WorkspacesView.h"


@@ -351,7 +353,7 @@ ServerWindow::_Show()
fDesktop->ShowWindow(fWindow);
if (fDirectWindowInfo && fDirectWindowInfo->IsFullScreen())
_ResizeToFullScreen();
-
+
fDesktop->LockSingleWindow();
}

@@ -2238,7 +2240,17 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
// NOTE: the region is not copied, Painter keeps a pointer,
// that's why you need to use the clipping only for as long
// as you have it locked
- drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
+
+ // NOTE: Making this copy (even using the RegionPool) is wasteful,
but, in
+ // the common case, less wasteful than de-converting
fCurrentDrawingRegion
+ // to avoid accumulative conversion errors.
+ // **Keeping fCurrentDrawingRegion in the proper coordinate space for
its
+ // entire life should be investigated, though it is highy probable that
the
+ // numerous micro-conversions would be a hinderence to performance in
views
+ // with many drawing calls. So this may be better - however unfortunate.
+ BRegion* drawingRegion = fWindow->GetRegion(fCurrentDrawingRegion);
+ fWindow->ConvertScreenToDrawing(drawingRegion);
+ drawingEngine->ConstrainClippingRegion(drawingRegion);

switch (code) {
case AS_STROKE_LINE:
@@ -2254,8 +2266,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
info.endPoint.x, info.endPoint.y));

BPoint penPos = info.endPoint;
-
fCurrentView->ConvertToScreenForDrawing(&info.startPoint);
- fCurrentView->ConvertToScreenForDrawing(&info.endPoint);
+ fCurrentView->ConvertForDrawing(&info.startPoint);
+ fCurrentView->ConvertForDrawing(&info.endPoint);
drawingEngine->StrokeLine(info.startPoint,
info.endPoint);

// We update the pen here because many DrawingEngine
calls which
@@ -2279,7 +2291,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top,
rect.right,
rect.bottom));

- fCurrentView->ConvertToScreenForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(&rect);
drawingEngine->InvertRect(rect);
break;
}
@@ -2294,7 +2306,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top,
rect.right,
rect.bottom));

- fCurrentView->ConvertToScreenForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(&rect);
drawingEngine->StrokeRect(rect);
break;
}
@@ -2309,7 +2321,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top,
rect.right,
rect.bottom));

- fCurrentView->ConvertToScreenForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(&rect);
drawingEngine->FillRect(rect);
break;
}
@@ -2326,8 +2338,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top,
rect.right,
rect.bottom));

- fCurrentView->ConvertToScreenForDrawing(&rect);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillRect(rect, *gradient);
delete gradient;
break;
@@ -2356,7 +2368,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
info.viewRect.left, info.viewRect.top,
info.viewRect.right,
info.viewRect.bottom));

-
fCurrentView->ConvertToScreenForDrawing(&info.viewRect);
+ fCurrentView->ConvertForDrawing(&info.viewRect);

// TODO: Unbreak...
// if ((info.options & B_WAIT_FOR_RETRACE) != 0)
@@ -2382,7 +2394,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read<float>(&span) != B_OK)
break;

- fCurrentView->ConvertToScreenForDrawing(&r);
+ fCurrentView->ConvertForDrawing(&r);
drawingEngine->DrawArc(r, angle, span, code ==
AS_FILL_ARC);
break;
}
@@ -2399,8 +2411,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
- fCurrentView->ConvertToScreenForDrawing(&r);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&r);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillArc(r, angle, span, *gradient);
delete gradient;
break;
@@ -2415,7 +2427,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
status_t status;
for (int32 i = 0; i < 4; i++) {
status = link.Read<BPoint>(&(pts[i]));
-
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
+ fCurrentView->ConvertForDrawing(&pts[i]);
}
if (status != B_OK)
break;
@@ -2431,12 +2443,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BPoint pts[4];
for (int32 i = 0; i < 4; i++) {
link.Read<BPoint>(&(pts[i]));
-
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
+ fCurrentView->ConvertForDrawing(&pts[i]);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillBezier(pts, *gradient);
delete gradient;
break;
@@ -2451,7 +2463,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read<BRect>(&rect) != B_OK)
break;

- fCurrentView->ConvertToScreenForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(&rect);
drawingEngine->DrawEllipse(rect, code ==
AS_FILL_ELLIPSE);
break;
}
@@ -2465,8 +2477,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
- fCurrentView->ConvertToScreenForDrawing(&rect);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillEllipse(rect, *gradient);
delete gradient;
break;
@@ -2504,8 +2516,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
- fCurrentView->ConvertToScreenForDrawing(&rect);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillRoundRect(rect, xrad, yrad,
*gradient);
delete gradient;
break;
@@ -2521,13 +2533,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,

for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
-
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
+ fCurrentView->ConvertForDrawing(&pts[i]);
}

if (link.Read<BRect>(&rect) != B_OK)
break;

- fCurrentView->ConvertToScreenForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(&rect);
drawingEngine->DrawTriangle(pts, rect, code ==
AS_FILL_TRIANGLE);
break;
}
@@ -2540,14 +2552,14 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BRect rect;
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
-
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
+ fCurrentView->ConvertForDrawing(&pts[i]);
}
link.Read<BRect>(&rect);
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
- fCurrentView->ConvertToScreenForDrawing(&rect);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&rect);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillTriangle(pts, rect, *gradient);
delete gradient;
break;
@@ -2570,8 +2582,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BPoint* pointList = new(nothrow) BPoint[pointCount];
if (link.Read(pointList, pointCount * sizeof(BPoint))

= B_OK) {
for (int32 i = 0; i < pointCount; i++)
-
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
-
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
+
fCurrentView->ConvertForDrawing(&pointList[i]);
+ fCurrentView->ConvertForDrawing(&polyFrame);

drawingEngine->DrawPolygon(pointList,
pointCount, polyFrame,
code == AS_FILL_POLYGON, isClosed &&
pointCount > 2);
@@ -2595,9 +2607,9 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read(pointList, pointCount * sizeof(BPoint))
== B_OK
&& link.ReadGradient(&gradient) == B_OK) {
for (int32 i = 0; i < pointCount; i++)
-
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
-
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
-
fCurrentView->ConvertToScreenForDrawing(gradient);
+
fCurrentView->ConvertForDrawing(&pointList[i]);
+ fCurrentView->ConvertForDrawing(&polyFrame);
+ fCurrentView->ConvertForDrawing(gradient);

drawingEngine->FillPolygon(pointList,
pointCount,
polyFrame, *gradient, isClosed &&
pointCount > 2);
@@ -2631,8 +2643,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
=
fCurrentView->CurrentState()->PenLocation();
shapeFrame.OffsetBy(screenOffset);

-
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
-
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
+ fCurrentView->ConvertForDrawing(&screenOffset);
+ fCurrentView->ConvertForDrawing(&shapeFrame);

drawingEngine->DrawShape(shapeFrame, opCount,
opList, ptCount,
ptList, code == AS_FILL_SHAPE,
screenOffset,
@@ -2669,9 +2681,9 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
=
fCurrentView->CurrentState()->PenLocation();
shapeFrame.OffsetBy(screenOffset);

-
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
-
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
-
fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&screenOffset);
+ fCurrentView->ConvertForDrawing(&shapeFrame);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillShape(shapeFrame, opCount,
opList,
ptCount, ptList, *gradient,
screenOffset,
fCurrentView->Scale());
@@ -2690,7 +2702,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.ReadRegion(&region) < B_OK)
break;

- fCurrentView->ConvertToScreenForDrawing(&region);
+ fCurrentView->ConvertForDrawing(&region);
drawingEngine->FillRegion(region);

break;
@@ -2707,8 +2719,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.ReadGradient(&gradient) != B_OK)
break;

- fCurrentView->ConvertToScreenForDrawing(&region);
- fCurrentView->ConvertToScreenForDrawing(gradient);
+ fCurrentView->ConvertForDrawing(&region);
+ fCurrentView->ConvertForDrawing(gradient);
drawingEngine->FillRegion(region, *gradient);
delete gradient;
break;
@@ -2748,9 +2760,9 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,

// Convert to screen coords and draw
for (int32 i = 0; i < lineCount; i++) {
- fCurrentView->ConvertToScreenForDrawing(
+ fCurrentView->ConvertForDrawing(
&lineData[i].startPoint);
- fCurrentView->ConvertToScreenForDrawing(
+ fCurrentView->ConvertForDrawing(
&lineData[i].endPoint);
}
drawingEngine->StrokeLineArray(lineCount, lineData);
@@ -2796,11 +2808,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_DRAW_STRING, View:
%s "
"-> %s\n", Title(), fCurrentView->Name(),
string));

- fCurrentView->ConvertToScreenForDrawing(&info.location);
+ fCurrentView->ConvertForDrawing(&info.location);
BPoint penLocation = drawingEngine->DrawString(string,
info.stringLength, info.location, delta);

- fCurrentView->ConvertFromScreenForDrawing(&penLocation);
+ fCurrentView->ConvertFromDrawing(&penLocation);

fCurrentView->CurrentState()->SetPenLocation(penLocation);

if (string != stackString)
@@ -2854,12 +2866,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
"-> %s\n", Title(), fCurrentView->Name(),
string));

for (int32 i = 0; i < glyphCount; i++)
-
fCurrentView->ConvertToScreenForDrawing(&locations[i]);
+ fCurrentView->ConvertForDrawing(&locations[i]);

BPoint penLocation = drawingEngine->DrawString(string,
stringLength, locations);

- fCurrentView->ConvertFromScreenForDrawing(&penLocation);
+ fCurrentView->ConvertFromDrawing(&penLocation);

fCurrentView->CurrentState()->SetPenLocation(penLocation);

break;
@@ -2906,6 +2918,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
break;
}

+ fWindow->DrawFromBuffer(drawingRegion);
+ fWindow->RecycleRegion(drawingRegion);
drawingEngine->UnlockParallelAccess();
}

@@ -2985,7 +2999,6 @@ ServerWindow::_DispatchPictureMessage(int32 code,
BPrivate::LinkReceiver& link)

case AS_VIEW_SET_LINE_MODE:
{
-
ViewSetLineModeInfo info;
link.Read<ViewSetLineModeInfo>(&info);

@@ -3616,10 +3629,21 @@ Window*
ServerWindow::MakeWindow(BRect frame, const char* name,
window_look look, window_feel feel, uint32 flags, uint32 workspace)
{
- // The non-offscreen ServerWindow uses the DrawingEngine instance from
- // the desktop.
- return new(std::nothrow) ::Window(frame, name, look, feel, flags,
+
+ ::Window* window = new(std::nothrow) ::Window(frame, name, look, feel,
flags,
workspace, this,
fDesktop->HWInterface()->CreateDrawingEngine());
+
+ // 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/View.cpp b/src/servers/app/View.cpp
index 7831b45..4995018 100644
--- a/src/servers/app/View.cpp
+++ b/src/servers/app/View.cpp
@@ -20,6 +20,7 @@
#include "DrawingEngine.h"
#include "DrawState.h"
#include "Overlay.h"
+#include "RapidDebug.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
#include "ServerCursor.h"
@@ -99,6 +100,7 @@ View::View(IntRect frame, IntPoint scrollingOffset, const
char* name,
fVisible(true),
fBackgroundDirty(true),
fIsDesktopBackground(false),
+ fOffsetFromWindowValid(false),

fEventMask(0),
fEventOptions(0),
@@ -163,6 +165,7 @@ View::Bounds() const
void
View::ConvertToVisibleInTopView(IntRect* bounds) const
{
+ InvalidateOffsetFromWindow();
*bounds = *bounds & Bounds();
// NOTE: this step is necessary even if we don't have a parent!
ConvertToParent(bounds);
@@ -175,6 +178,9 @@ View::ConvertToVisibleInTopView(IntRect* bounds) const
void
View::AttachedToWindow(::Window* window)
{
+ InvalidateOffsetFromWindow();
+ // always invalid when first attached.
+
fWindow = window;

// an ugly hack to detect the desktop background
@@ -246,6 +252,7 @@ View::AddChild(View* view)
return;
}

+ InvalidateOffsetFromWindow();
view->fParent = this;

if (!fLastChild) {
@@ -468,12 +475,66 @@ View::SetName(const char* string)
void
View::SetFlags(uint32 flags)
{
+ InvalidateOffsetFromWindow();
fFlags = flags;
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
}


void
+View::SetDrawingOrigin(BPoint origin)
+{
+ InvalidateOffsetFromWindow();
+ fDrawState->SetOrigin(origin);
+
+ // rebuild clipping
+ if (fDrawState->HasClipping())
+ RebuildClipping(false);
+}
+
+
+BPoint
+View::DrawingOrigin() const
+{
+ BPoint origin(fDrawState->Origin());
+ float scale = Scale();
+
+ origin.x *= scale;
+ origin.y *= scale;
+
+ return origin;
+}
+
+
+void
+View::SetScale(float scale)
+{
+ fDrawState->SetScale(scale);
+
+ // rebuild clipping
+ if (fDrawState->HasClipping())
+ RebuildClipping(false);
+}
+
+
+float
+View::Scale() const
+{
+ return CurrentState()->Scale();
+}
+
+
+void
+View::SetUserClipping(const BRegion* region)
+{
+ fDrawState->SetClippingRegion(region);
+
+ // rebuild clipping (for just this view)
+ RebuildClipping(false);
+}
+
+
+void
View::SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect,
IntRect destRect, int32 resizingMode, int32 options)
{
@@ -555,6 +616,35 @@ View::UpdateOverlay()
// #pragma mark -


+/*! Get the value for the offset of the view's origin to the window.
+ *
+ * Calculating the offset from the window involves iterating over all
+ * parent views and adding the parent's offset to its parent until the
+ * window is reached. As this offset needs to be calculated for every
+ * drawing operation - and the offset rarely changes - this function
+ * caches the result from previous runs, using events to invalidate the
+ * cached result when it is possible for it to have changed (such as when
+ * the view (or a parent) is moved or resized.
+ */
+const BPoint&
+View::_GetOffsetFromWindow() const
+{
+ if (fOffsetFromWindowValid == false){
+ fOffsetFromWindow = BPoint(0,0);;
+ ConvertToParent(&fOffsetFromWindow);
+
+ View * parent = fParent;
+ while (parent != NULL && parent->fParent != NULL){
+ parent->ConvertToParent(&fOffsetFromWindow);
+ parent = parent->fParent;
+ }
+ fOffsetFromWindowValid = true;
+ }
+
+ return fOffsetFromWindow;
+}
+
+
void
View::ConvertToParent(BPoint* point) const
{
@@ -754,6 +844,289 @@ View::ConvertFromScreen(BRegion* region) const
}


+// #pragma mark ConvertToWindow
+
+/*! ConvertToWindow(...) functions convert rects, points, regions, or
+ * gradients from the local (view) coordinate system to the Window
+ * coordinate system.
+ */
+void
+View::ConvertToWindow(BPoint* point) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ point->x += offset.x;
+ point->y += offset.y;
+}
+
+
+void
+View::ConvertToWindow(IntPoint* point) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ point->x += (int32)offset.x;
+ point->y += (int32)offset.y;
+}
+
+
+void
+View::ConvertToWindow(BRect* rect) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ rect->OffsetBy(offset);
+}
+
+
+void
+View::ConvertToWindow(IntRect* rect) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ rect->OffsetBy(offset);
+}
+
+
+void
+View::ConvertToWindow(BRegion* region) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ region->OffsetBy(offset);
+}
+
+
+// #pragma mark ConvertFromWindow
+
+/*! ConvertFromWindow(...) functions convert rects, points, regions, or
+ * gradients from the window coordinate system to the local (view)
+ * coordinate system.
+ */
+void
+View::ConvertFromWindow(BPoint* point) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ point->x -= offset.x;
+ point->y -= offset.y;
+}
+
+
+void
+View::ConvertFromWindow(IntPoint* point) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ point->x -= (int32)offset.x;
+ point->y -= (int32)offset.y;
+}
+
+
+void
+View::ConvertFromWindow(BRect* rect) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ rect->OffsetBy(-offset);
+}
+
+
+void
+View::ConvertFromWindow(IntRect* rect) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ rect->OffsetBy(-offset);
+}
+
+
+void
+View::ConvertFromWindow(BRegion* region) const
+{
+ const BPoint& offset = _GetOffsetFromWindow();
+ region->OffsetBy(-offset);
+}
+
+
+// #pragma mark ConvertForDrawing
+
+
+//! converts point from view to drawing coordinate system
+void
+View::ConvertForDrawing(BPoint* point) const
+{
+ fDrawState->Transform(point);
+
+ ConvertToWindow(point);
+
+ if (fWindow)
+ fWindow->ConvertViewToDrawing(point);
+}
+
+
+//! converts rect from view to drawing coordinate system
+void
+View::ConvertForDrawing(BRect* rect) const
+{
+ fDrawState->Transform(rect);
+
+ ConvertToWindow(rect);
+
+ if (fWindow)
+ fWindow->ConvertViewToDrawing(rect);
+}
+
+
+//! converts rect from view to drawing coordinate system
+void
+View::ConvertForDrawing(IntRect* rect) const
+{
+ //fDrawState->Transform(rect); // TODO!!!!
+
+ ConvertToWindow(rect);
+ if (fWindow)
+ fWindow->ConvertViewToDrawing(rect);
+}
+
+
+//! converts region from view to drawing coordinate system
+void
+View::ConvertForDrawing(BRegion* region) const
+{
+ fDrawState->Transform(region);
+
+ ConvertToWindow(region);
+ if (fWindow)
+ fWindow->ConvertViewToDrawing(region);
+}
+
+
+//! converts a gradient from local to drawing coordinate system
+void
+View::ConvertForDrawing(BGradient* gradient) const
+{
+ switch(gradient->GetType()) {
+ case BGradient::TYPE_LINEAR: {
+ BGradientLinear* linear = (BGradientLinear*) gradient;
+ BPoint start = linear->Start();
+ BPoint end = linear->End();
+ fDrawState->Transform(&start);
+ ConvertForDrawing(&start);
+ fDrawState->Transform(&end);
+ ConvertForDrawing(&end);
+ linear->SetStart(start);
+ linear->SetEnd(end);
+ linear->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_RADIAL: {
+ BGradientRadial* radial = (BGradientRadial*) gradient;
+ BPoint center = radial->Center();
+ fDrawState->Transform(&center);
+ ConvertForDrawing(&center);
+ radial->SetCenter(center);
+ radial->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_RADIAL_FOCUS: {
+ BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
+ BPoint center = radialFocus->Center();
+ BPoint focal = radialFocus->Focal();
+ fDrawState->Transform(&center);
+ ConvertForDrawing(&center);
+ fDrawState->Transform(&focal);
+ ConvertForDrawing(&focal);
+ radialFocus->SetCenter(center);
+ radialFocus->SetFocal(focal);
+ radialFocus->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_DIAMOND: {
+ BGradientDiamond* diamond = (BGradientDiamond*)
gradient;
+ BPoint center = diamond->Center();
+ fDrawState->Transform(&center);
+ ConvertForDrawing(&center);
+ diamond->SetCenter(center);
+ diamond->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_CONIC: {
+ BGradientConic* conic = (BGradientConic*) gradient;
+ BPoint center = conic->Center();
+ fDrawState->Transform(&center);
+ ConvertForDrawing(&center);
+ conic->SetCenter(center);
+ conic->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_NONE: {
+ break;
+ }
+ }
+}
+
+
+//! converts points from local to drawing coordinate system
+void
+View::ConvertForDrawing(BPoint* dst, const BPoint* src, int32 num) const
+{
+ // TODO: optimize this, it should be smarter
+ while (num--) {
+ *dst = *src;
+ fDrawState->Transform(dst);
+
+ ConvertForDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+//! converts rects from local to drawing coordinate system
+void
+View::ConvertForDrawing(BRect* dst, const BRect* src, int32 num) const
+{
+ // TODO: optimize this, it should be smarter
+ while (num--) {
+ *dst = *src;
+ fDrawState->Transform(dst);
+
+ ConvertForDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+//! converts regions from local to drawing coordinate system
+void
+View::ConvertForDrawing(BRegion* dst, const BRegion* src, int32 num) const
+{
+ // TODO: optimize this, it should be smarter
+ while (num--) {
+ *dst = *src;
+ fDrawState->Transform(dst);
+
+ ConvertForDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+//! converts point from drawing coordinate system to local coordinate system
+void
+View::ConvertFromDrawing(BPoint* point) const
+{
+ if (fWindow)
+ fWindow->ConvertDrawingToWindow(point);
+
+ ConvertFromWindow(point);
+ fDrawState->InverseTransform(point);
+}
+
+
+//! converts a point from screen to local coordinate system
+void
+View::ConvertFromScreenForDrawing(BPoint* point) const
+{
+ ConvertFromScreen(point);
+ fDrawState->InverseTransform(point);
+}
+
+
// #pragma mark -


@@ -775,7 +1148,8 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
// local clipping to see which parts need invalidation
IntRect oldVisibleBounds(newVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
- ConvertToScreen(&oldVisibleBounds);
+ //ConvertToScreen(&oldVisibleBounds);
+ ConvertForDrawing(&oldVisibleBounds);

ConvertToVisibleInTopView(&newVisibleBounds);

@@ -788,7 +1162,8 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
IntRect oldVisibleBounds(Bounds());
IntRect newVisibleBounds(oldVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
- ConvertToScreen(&oldVisibleBounds);
+ //ConvertToScreen(&oldVisibleBounds);
+ ConvertForDrawing(&oldVisibleBounds);

// NOTE: using ConvertToVisibleInTopView()
// instead of ConvertToScreen()! see below
@@ -827,6 +1202,10 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
// the screen clipping
InvalidateScreenClipping();
}
+
+ // We need to tell all of our children invalidate their offsets:
+ // And they need to tell our grand-children the same...
+ InvalidateOffsetFromWindow(true);
}


@@ -875,7 +1254,7 @@ View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
}
}

- ConvertToScreen(dirty);
+ ConvertForDrawing(dirty);
dirtyRegion->Include(dirty);
}
fWindow->RecycleRegion(dirty);
@@ -894,6 +1273,8 @@ View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
// TODO: when the implementation of Hide() and Show() is
// complete, see if this should be avoided
RebuildClipping(false);
+
+ InvalidateOffsetFromWindow(true);
}


@@ -919,6 +1300,7 @@ View::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
// know, stippi should look into this when he's back :)
InvalidateScreenClipping();
}
+// InvalidateOffsetFromWindow(true);
}


@@ -975,6 +1357,7 @@ View::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)

// the screen clipping of this view and it's
// childs is no longer valid
+ InvalidateOffsetFromWindow(true);
InvalidateScreenClipping();
RebuildClipping(false);
}
@@ -1165,13 +1548,16 @@ View::Draw(DrawingEngine* drawingEngine, BRegion*
effectiveClipping,
// add the current clipping
redraw->IntersectWith(effectiveClipping);

+ if (fWindow != NULL)
+ fWindow->ConvertScreenToDrawing(redraw);
+
Overlay* overlayCookie = _Overlay();

if (fViewBitmap != NULL && overlayCookie == NULL) {
// draw view bitmap
// TODO: support other options!
BRect rect = fBitmapDestination;
- ConvertToScreenForDrawing(&rect);
+ ConvertForDrawing(&rect);

align_rect_to_pixels(&rect);

@@ -1192,6 +1578,7 @@ View::Draw(DrawingEngine* drawingEngine, BRegion*
effectiveClipping,
// lock the drawing engine for as long as we need the
clipping
// to be valid
if (rect.IsValid()/* && drawingEngine->Lock()*/) {
+
drawingEngine->ConstrainClippingRegion(redraw);

drawing_mode oldMode;
@@ -1425,6 +1812,23 @@ View::AddTokensForViewsInRegion(BPrivate::PortLink&
link, BRegion& region,
}


+/*! Used by parent views, and internally, to trigger recalculation of our
+ * offset to our window (or-top-most parent if we have no window).
+ */
+void
+View::InvalidateOffsetFromWindow(bool deep) const
+{
+ fOffsetFromWindowValid = false;
+
+ if (deep == false)
+ return;
+
+ // Tell our children!
+ for (View* child = FirstChild(); child; child = child->NextSibling())
+ child->InvalidateOffsetFromWindow(deep);
+}
+
+
void
View::PrintToStream() const
{
@@ -1533,13 +1937,19 @@ View::ScreenAndUserClipping(BRegion*
windowContentClipping, bool force) const
return *fScreenAndUserClipping;

// build a new combined user and screen clipping
- fScreenAndUserClipping = new (nothrow) BRegion(*fUserClipping);
+ if (fWindow == NULL)
+ fScreenAndUserClipping = new (nothrow) BRegion(*fUserClipping);
+ else
+ fScreenAndUserClipping = fWindow->GetRegion(*fUserClipping);
+
if (fScreenAndUserClipping == NULL)
return fScreenClipping;

ConvertToScreen(fScreenAndUserClipping);
+
fScreenAndUserClipping->IntersectWith(
&_ScreenClipping(windowContentClipping, force));
+
return *fScreenAndUserClipping;
}

diff --git a/src/servers/app/View.h b/src/servers/app/View.h
index b2291af..9dca38b 100644
--- a/src/servers/app/View.h
+++ b/src/servers/app/View.h
@@ -136,6 +136,34 @@ public:
void ConvertFromScreen(IntRect*
rect) const;
void ConvertFromScreen(BRegion*
region) const;

+ void ConvertToWindow(BPoint* point)
const;
+ void ConvertToWindow(IntPoint*
point) const;
+ void ConvertToWindow(BRect* rect)
const;
+ void ConvertToWindow(IntRect* rect)
const;
+ void ConvertToWindow(BRegion*
region) const;
+
+ void ConvertFromWindow(BPoint*
point) const;
+ void ConvertFromWindow(IntPoint*
point) const;
+ void ConvertFromWindow(BRect* rect)
const;
+ void ConvertFromWindow(IntRect*
rect) const;
+ void ConvertFromWindow(BRegion*
region) const;
+
+ // convert from local coordinate space to
RenderingEngine's
+ // coordinate space (which is the WindowBuffer or
screen).
+ void ConvertForDrawing(BPoint*
point) const;
+ void ConvertForDrawing(BRect* rect)
const;
+ void ConvertForDrawing(BRegion*
region) const;
+ void ConvertForDrawing(IntRect*
rect) const;
+
+ void ConvertForDrawing(BGradient*
gradient) const;
+ void ConvertForDrawing(BPoint* dst,
const BPoint* src, int32 num) const;
+ void ConvertForDrawing(BRect* dst,
const BRect* src, int32 num) const;
+ void ConvertForDrawing(BRegion* dst,
const BRegion* src, int32 num) const;
+
+ void ConvertFromDrawing(BPoint*
point) const;
+ void
ConvertFromScreenForDrawing(BPoint* point) const;
+ // used when updating the pen position
+
void MoveBy(int32 dx, int32 dy,
BRegion*
dirtyRegion);

@@ -227,6 +255,8 @@ public:

&& fScreenAndUserClipping != NULL));
}

+ virtual void InvalidateOffsetFromWindow(bool deep =
false) const;
+
// debugging
void PrintToStream() const;
#if 0
@@ -235,6 +265,7 @@ public:
#endif

protected:
+ inline const BPoint& _GetOffsetFromWindow() const;
BRegion& _ScreenClipping(BRegion*
windowContentClipping,
bool force =
false) const;
void _MoveScreenClipping(int32 x,
int32 y,
@@ -262,6 +293,7 @@ protected:
bool fVisible : 1;
bool fBackgroundDirty : 1;
bool fIsDesktopBackground : 1;
+ mutable bool fOffsetFromWindowValid :1;

uint32 fEventMask;
uint32 fEventOptions;
@@ -277,6 +309,8 @@ protected:
ServerCursor* fCursor;
ServerPicture* fPicture;

+ mutable BPoint fOffsetFromWindow;
+
// clipping
BRegion fLocalClipping;

diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp
index 117e67a..5b70d08 100644
--- a/src/servers/app/Window.cpp
+++ b/src/servers/app/Window.cpp
@@ -20,6 +20,11 @@
#include <Debug.h>

#include <DirectWindow.h>
+#include <GradientLinear.h>
+#include <GradientRadial.h>
+#include <GradientRadialFocus.h>
+#include <GradientDiamond.h>
+#include <GradientConic.h>
#include <PortLink.h>
#include <View.h>
#include <ViewPrivate.h>
@@ -33,9 +38,11 @@
#include "HWInterface.h"
#include "MessagePrivate.h"
#include "PortLink.h"
+#include "RapidDebug.h"
#include "ServerApp.h"
#include "ServerWindow.h"
#include "WindowBehaviour.h"
+#include "WindowBuffer.h"
#include "Workspace.h"
#include "WorkspacesView.h"

@@ -94,6 +101,7 @@ Window::Window(const BRect& frame, const char *name,
fTopView(NULL),
fWindow(window),
fDrawingEngine(drawingEngine),
+ fDecoratorDrawingEngine(drawingEngine),
fDesktop(window->Desktop()),

fCurrentUpdateSession(&fUpdateSessions[0]),
@@ -119,7 +127,8 @@ Window::Window(const BRect& frame, const char *name,
fMinHeight(1),
fMaxHeight(32768),

- fWorkspacesViewCount(0)
+ fWorkspacesViewCount(0),
+ fWindowBuffer(NULL)
{
_InitWindowStack();

@@ -169,6 +178,9 @@ Window::Window(const BRect& frame, const char *name,

Window::~Window()
{
+ if (IsWindowBufferEnabled())
+ _LOG("Buffered window destroyed\n");
+
if (fTopView) {
fTopView->DetachedFromWindow();
delete fTopView;
@@ -178,6 +190,7 @@ Window::~Window()

delete fWindowBehaviour;
delete fDrawingEngine;
+ delete fWindowBuffer;

gDecorManager.CleanupForWindow(this);
}
@@ -368,6 +381,9 @@ Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion,
bool resizeStack)
fFrame.right += x;
fFrame.bottom += y;

+ if (IsWindowBufferEnabled())
+ WindowBuffer()->ResizeTo(fFrame.Width(), fFrame.Height());
+
fContentRegionValid = false;
fEffectiveDrawingRegionValid = false;

@@ -389,6 +405,10 @@ Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion,
bool resizeStack)
}
}

+ // Just in case our top view isn't anchored to origin...
+ if (fTopView != NULL)
+ fTopView->InvalidateOffsetFromWindow(true);
+
// send a message to the client informing about the changed size
BRect frame(Frame());
BMessage msg(B_WINDOW_RESIZED);
@@ -581,6 +601,53 @@ Window::Decorator() const


bool
+Window::SetWindowBufferEnabled(bool enable)
+{
+ if ((Flags() & B_NO_BUFFERED_DRAWING) != 0)
+ return false;
+
+ // already enabled/disabled? Then we're done!
+ if ((enable && IsWindowBufferEnabled())
+ || (!enable && IsWindowBufferEnabled() == false))
+ return true;
+
+ ::Decorator* decorator = Decorator();
+
+ // DrawingEngine's SetDrawingBuffer handles the locking.
+ if (enable) {
+ if (fWindowBuffer == NULL)
+ fWindowBuffer = new(std::nothrow) ::WindowBuffer(this);
+
+ // TODO! This code doesn't take into account the future
+ // requirement of having fDecorator draw in the WindowBuffer
+ // along with the Window.
+
+ if (decorator != NULL) {
+ fDecoratorDrawingEngine
+ =
fDesktop->HWInterface()->CreateDrawingEngine();
+ decorator->SetDrawingEngine(fDecoratorDrawingEngine);
+ }
+
+ fDrawingEngine->SetDrawingBuffer(fWindowBuffer);
+ }else{
+ if (fDecoratorDrawingEngine != fDrawingEngine)
+ delete fDecoratorDrawingEngine;
+
+ fDecoratorDrawingEngine = fDrawingEngine;
+ if (decorator != NULL)
+ decorator->SetDrawingEngine(fDecoratorDrawingEngine);
+
+ fDrawingEngine->SetDrawingBuffer(NULL);
+ delete fWindowBuffer;
+ fWindowBuffer = NULL;
+ }
+
+ ServerWindow()->RequestRedraw();
+ return true;
+}
+
+
+bool
Window::ReloadDecor()
{
::Decorator* decorator = NULL;
@@ -724,7 +791,7 @@ Window::ProcessDirtyRegion(BRegion& region)
// the region as it likes.
ServerWindow()->RequestRedraw();
}
-
+
fDirtyRegion.Include(&region);
fDirtyCause |= UPDATE_EXPOSE;
}
@@ -743,8 +810,8 @@ Window::RedrawDirtyRegion()
if (IsVisible()) {
_DrawBorder();

- BRegion* dirtyContentRegion =
- fRegionPool.GetRegion(VisibleContentRegion());
+ BRegion* dirtyContentRegion
+ = fRegionPool.GetRegion(VisibleContentRegion());
dirtyContentRegion->IntersectWith(&fDirtyRegion);

_TriggerContentRedraw(*dirtyContentRegion);
@@ -765,6 +832,45 @@ Window::RedrawDirtyRegion()


void
+Window::DrawFromBuffer(BRegion* drawingRegion)
+{
+ if (IsWindowBufferEnabled() == false)
+ return;
+
+ DrawingEngine* draw = fDesktop->GetDrawingEngine();
+
+ BRegion* screenRegion = GetRegion(*drawingRegion);
+ ConvertDrawingToScreen(screenRegion);
+
+ fDrawingEngine->LockParallelAccess();
+ draw->LockParallelAccess();
+
+ draw->ConstrainClippingRegion(screenRegion);
+
+ BRect sourceRect;
+ BRect destinationRect;
+
+ for (int32 i = 0; i < drawingRegion->CountRects(); ++i) {
+ sourceRect = drawingRegion->RectAt(i);
+ destinationRect = sourceRect;
+
+ ConvertDrawingToScreen(&destinationRect);
+
+// _LOGF("DFB: (%.0f, %.0f, %.0f, %.0f) : (%.0f, %.0f,
%.0f, %.0f)\n",
+// sourceRect.left, sourceRect.top,
sourceRect.right,
+// sourceRect.bottom, destinationRect.left,
destinationRect.top,
+// destinationRect.right, destinationRect.bottom);
+
+ draw->DrawBuffer(WindowBuffer(), sourceRect,
destinationRect, 0);
+ }
+
+ RecycleRegion(screenRegion);
+ draw->UnlockParallelAccess();
+ fDrawingEngine->UnlockParallelAccess();
+}
+
+
+void
Window::MarkDirty(BRegion& regionOnScreen)
{
// for marking any part of the desktop dirty
@@ -823,8 +929,6 @@ Window::InvalidateView(View* view, BRegion& viewRegion)
viewRegion.IntersectWith(
&view->ScreenAndUserClipping(&fContentRegion));

-//fDrawingEngine->FillRegion(viewRegion, rgb_color{ 0, 255, 0, 255 });
-//snooze(10000);
fDirtyCause |= UPDATE_REQUEST;
_TriggerContentRedraw(viewRegion);
}
@@ -1922,6 +2026,9 @@ Window::BeginUpdate(BPrivate::PortLink& link)
//fDrawingEngine->FillRegion(*dirty, sCurrentColor);
//snooze(10000);
//}
+
+ if (IsWindowBufferEnabled())
+ fWindowBuffer->ClientDrawLock();

link.StartMessage(B_OK);
// append the current window geometry to the
@@ -1959,6 +2066,9 @@ Window::EndUpdate()
// NOTE: see comment in _BeginUpdate()

if (fInUpdate) {
+ if (IsWindowBufferEnabled())
+ fWindowBuffer->ClientDrawUnlock();
+
// reenable copy to front
fDrawingEngine->SetCopyToFrontEnabled(true);

@@ -1968,7 +2078,34 @@ Window::EndUpdate()
if (dirty) {
dirty->IntersectWith(&VisibleContentRegion());

+ // If we are buffering, we need to now draw the
+ // WindowBuffer to the frame buffer.
+ // TODO: when compositing is enabled, merely indicate
the
+ // client has complete drawing and unlock the
WindowBuffer.
+ if (IsWindowBufferEnabled()) {
+
+ DrawingEngine* draw =
fDesktop->GetDrawingEngine();
+
+ BRect sourceRect;
+ BRect destinationRect;
+ draw->LockParallelAccess();
+ draw->ConstrainClippingRegion(dirty);
+ for (int32 i = 0; i < dirty->CountRects(); ++i)
{
+ destinationRect = dirty->RectAt(i);
+
+ sourceRect = destinationRect;
+ ConvertScreenToDrawing(&sourceRect);
+
+ draw->DrawBuffer(WindowBuffer(),
sourceRect,
+ destinationRect);
+ }
+ draw->CopyToFront(*dirty);
+ draw->Sync();
+ draw->UnlockParallelAccess();
+ }
+
fDrawingEngine->CopyToFront(*dirty);
+
fRegionPool.Recycle(dirty);
}

@@ -2133,7 +2270,8 @@ Window::DetachFromWindowStack(bool ownStackNeeded)
Window* remainingTop = fCurrentStack->TopLayerWindow();
if (remainingTop != NULL) {
if (decorator != NULL)
-
decorator->SetDrawingEngine(remainingTop->fDrawingEngine);
+ decorator->SetDrawingEngine(
+ remainingTop->GetDecoratorDrawingEngine());
// propagate focus to the decorator
remainingTop->SetFocus(remainingTop->IsFocus());
remainingTop->SetLook(remainingTop->Look(), NULL);
@@ -2244,7 +2382,7 @@ Window::MoveToTopStackLayer()
::Decorator* decorator = Decorator();
if (decorator == NULL)
return false;
- decorator->SetDrawingEngine(fDrawingEngine);
+ decorator->SetDrawingEngine(fDecoratorDrawingEngine);
SetLook(Look(), NULL);
decorator->SetTopTab(PositionInStack());
return fCurrentStack->MoveToTopLayer(this);
@@ -2270,6 +2408,273 @@ Window::MoveToStackPosition(int32 to, bool isMoving)
}


+// #pragma mark Coordinate Conversion
+
+
+/*! Convert coordinates between view and drawing coordinate spaces.
+ *
+ * The drawing coordinate space is dynamic, possibly changing even while
+ * this window exists. When we have no WindowBuffer we are drawing
directly
+ * to the screen - so the screen's coordinate space is the same as the
+ * drawing coordinate space. However, when we have a WindowBuffer, the
+ * drawing coordinate space is held within the buffer. Here, too, things
are
+ * note completely straight-forward - it is not just possible, but likely,
+ * that WindowBuffer is further modifying the coordinate space to
accomodate
+ * for a Decorator, shadows, resizing optimizations, or other reasons.
+ */
+void
+Window::ConvertViewToDrawing(BPoint* point) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false) {
+ point->x += wf.left;
+ point->y += wf.top;
+ } else
+ WindowBuffer()->ConvertToBuffer(point);
+}
+
+
+void
+Window::ConvertViewToDrawing(BRect* rect) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false)
+ rect->OffsetBy((int32)wf.left, (int32)wf.top);
+ else
+ WindowBuffer()->ConvertToBuffer(rect);
+}
+
+
+void
+Window::ConvertViewToDrawing(BRegion* region) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false)
+ region->OffsetBy((int32)wf.left, (int32)wf.top);
+ else
+ WindowBuffer()->ConvertToBuffer(region);
+}
+
+
+void
+Window::ConvertViewToDrawing(BGradient* gradient) const
+{
+ switch(gradient->GetType()) {
+ case BGradient::TYPE_LINEAR: {
+ BGradientLinear* linear = (BGradientLinear*) gradient;
+ BPoint start = linear->Start();
+ BPoint end = linear->End();
+ ConvertViewToDrawing(&start);
+ ConvertViewToDrawing(&end);
+ linear->SetStart(start);
+ linear->SetEnd(end);
+ linear->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_RADIAL: {
+ BGradientRadial* radial = (BGradientRadial*) gradient;
+ BPoint center = radial->Center();
+ ConvertViewToDrawing(&center);
+ radial->SetCenter(center);
+ radial->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_RADIAL_FOCUS: {
+ BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
+ BPoint center = radialFocus->Center();
+ BPoint focal = radialFocus->Focal();
+ ConvertViewToDrawing(&center);
+ ConvertViewToDrawing(&focal);
+ radialFocus->SetCenter(center);
+ radialFocus->SetFocal(focal);
+ radialFocus->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_DIAMOND: {
+ BGradientDiamond* diamond = (BGradientDiamond*)
gradient;
+ BPoint center = diamond->Center();
+ ConvertViewToDrawing(&center);
+ diamond->SetCenter(center);
+ diamond->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_CONIC: {
+ BGradientConic* conic = (BGradientConic*) gradient;
+ BPoint center = conic->Center();
+ ConvertViewToDrawing(&center);
+ conic->SetCenter(center);
+ conic->SortColorStopsByOffset();
+ break;
+ }
+ case BGradient::TYPE_NONE: {
+ break;
+ }
+ }
+}
+
+
+void
+Window::ConvertViewToDrawing(IntRect* rect) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false)
+ rect->OffsetBy((int32)wf.left, (int32)wf.top);
+ else
+ WindowBuffer()->ConvertToBuffer(rect);
+}
+
+
+void
+Window::ConvertDrawingToWindow(BPoint* point) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false) {
+ point->x -= wf.left;
+ point->y -= wf.top;
+ } else
+ WindowBuffer()->ConvertFromBuffer(point);
+}
+
+
+void
+Window::ConvertDrawingToWindow(BRect* rect) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false)
+ rect->OffsetBy((int32)-wf.left, (int32)-wf.top);
+ else
+ WindowBuffer()->ConvertFromBuffer(rect);
+}
+
+
+void
+Window::ConvertDrawingToWindow(BRegion* region) const
+{
+ BRect wf = Frame();
+
+
+ if (IsWindowBufferEnabled() == false)
+ region->OffsetBy((int32)-wf.left, (int32)-wf.top);
+ else
+ WindowBuffer()->ConvertFromBuffer(region);
+}
+
+
+void
+Window::ConvertDrawingToWindow(IntRect* rect) const
+{
+ BRect wf = Frame();
+
+ if (IsWindowBufferEnabled() == false)
+ rect->OffsetBy((int32)-wf.left, (int32)-wf.top);
+ else
+ WindowBuffer()->ConvertFromBuffer(rect);
+}
+
+
+void
+Window::ConvertViewToDrawing(BPoint* dst, const BPoint* src, int32 num) const
+{
+ while (num--) {
+ *dst = *src;
+ ConvertViewToDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+void
+Window::ConvertViewToDrawing(BRect* dst, const BRect* src, int32 num) const
+{
+ while (num--) {
+ *dst = *src;
+ ConvertViewToDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+void
+Window::ConvertViewToDrawing(BRegion* dst, const BRegion* src, int32 num) const
+{
+ while (num--) {
+ *dst = *src;
+ ConvertViewToDrawing(dst);
+ src++;
+ dst++;
+ }
+}
+
+
+void
+Window::ConvertScreenToDrawing(BRect* rect) const
+{
+ if (IsWindowBufferEnabled() == false)
+ return;
+
+ ConvertScreenToWindow(rect);
+ WindowBuffer()->ConvertToBuffer(rect);
+}
+
+
+void
+Window::ConvertScreenToDrawing(BRegion* region) const
+{
+ if (IsWindowBufferEnabled() == false)
+ return;
+
+ ConvertScreenToWindow(region);
+ WindowBuffer()->ConvertToBuffer(region);
+}
+
+
+void
+Window::ConvertScreenToWindow(BRect* rect) const
+{
+ rect->OffsetBy(-(Frame().left), -(Frame().top));
+}
+
+
+void
+Window::ConvertScreenToWindow(BRegion* region) const
+{
+ region->OffsetBy(-(Frame().left), -(Frame().top));
+}
+
+
+void
+Window::ConvertDrawingToScreen(BRect* rect) const
+{
+ if (IsWindowBufferEnabled() == false)
+ return;
+
+ WindowBuffer()->ConvertFromBuffer(rect);
+ rect->OffsetBy(Frame().left, Frame().top);
+}
+
+
+void
+Window::ConvertDrawingToScreen(BRegion* region) const
+{
+ if (IsWindowBufferEnabled() == false)
+ return;
+
+ WindowBuffer()->ConvertFromBuffer(region);
+ region->OffsetBy(Frame().left, Frame().top);
+}
+
+
+// #pragma mark WindowStack
+
+
WindowStack*
Window::_InitWindowStack()
{
diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h
index 6817df2..6086a3d 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
SetWindowBufferEnabled(bool enable);
+
+ bool IsWindowBufferEnabled()
const
+ {
return WindowBuffer() != NULL; }

bool ReloadDecor();

@@ -145,6 +153,9 @@ public:
// generic version, used by the Desktop
void
ProcessDirtyRegion(BRegion& regionOnScreen);
void RedrawDirtyRegion();
+
+ // Draw from WindowBuffer to the frame buffer
+ void DrawFromBuffer(BRegion*
drawingRegion);

// can be used from inside classes that don't
// need to know about Desktop (first version uses
Desktop)
@@ -169,6 +180,9 @@ public:
DrawingEngine* GetDrawingEngine() const
{
return fDrawingEngine; }

+ DrawingEngine* GetDecoratorDrawingEngine()
const
+ {
return fDecoratorDrawingEngine; }
+
// managing a region pool
::RegionPool* RegionPool()
{
return &fRegionPool; }
@@ -309,6 +323,34 @@ public:
bool MoveToTopStackLayer();
bool
MoveToStackPosition(int32 index,
bool
isMoving);
+
+ virtual void ConvertViewToDrawing(BPoint* point)
const;
+ virtual void ConvertViewToDrawing(BRect* rect) const;
+ virtual void ConvertViewToDrawing(BRegion* region)
const;
+ virtual void ConvertViewToDrawing(IntRect* rect)
const;
+
+ virtual void ConvertDrawingToWindow(BPoint* point)
const;
+ virtual void ConvertDrawingToWindow(BRect* rect)
const;
+ virtual void ConvertDrawingToWindow(BRegion* region)
const;
+ virtual void ConvertDrawingToWindow(IntRect* rect)
const;
+
+ void ConvertViewToDrawing(BGradient*
gradient) const;
+ void ConvertViewToDrawing(BPoint*
dst,
+ const BPoint*
src, int32 num) const;
+ void ConvertViewToDrawing(BRect*
dst, const BRect* src,
+ int32 num)
const;
+ void ConvertViewToDrawing(BRegion*
dst,
+ const BRegion*
src, int32 num) const;
+
+ void ConvertScreenToDrawing(BRect*
rect) const;
+ void ConvertScreenToDrawing(BRegion*
region) const;
+ void ConvertScreenToWindow(BRect*
rect) const;
+ void ConvertScreenToWindow(BRegion*
region) const;
+
+ void ConvertDrawingToScreen(BRect*
rect) const;
+ void ConvertDrawingToScreen(BRegion*
region) const;
+
+
protected:
void
_ShiftPartOfRegion(BRegion* region,

BRegion* regionToShift, int32 xOffset,
@@ -365,6 +407,7 @@ protected:
View* fTopView;
::ServerWindow* fWindow;
DrawingEngine* fDrawingEngine;
+ DrawingEngine* fDecoratorDrawingEngine;
::Desktop* fDesktop;

// The synchronization, which client drawing commands
@@ -431,6 +474,8 @@ protected:

int32 fWorkspacesViewCount;

+ ::WindowBuffer* fWindowBuffer;
+
friend class DecorManager;

private:
diff --git a/src/servers/app/decorator/DecorManager.cpp
b/src/servers/app/decorator/DecorManager.cpp
index 59e6f53..d4f35b8 100644
--- a/src/servers/app/decorator/DecorManager.cpp
+++ b/src/servers/app/decorator/DecorManager.cpp
@@ -136,8 +136,8 @@ DecorManager::AllocateDecorator(Window* window)
if (window == fPreviewWindow) {
if (fPreviewDecor != NULL) {
return
fPreviewDecor->AllocateDecorator(window->Desktop(),
- window->GetDrawingEngine(), window->Frame(),
window->Title(),
- window->Look(), window->Flags());
+ window->GetDecoratorDrawingEngine(),
window->Frame(),
+ window->Title(), window->Look(),
window->Flags());
} else {
fPreviewWindow = NULL;
}
diff --git a/src/servers/app/drawing/DrawingEngine.cpp
b/src/servers/app/drawing/DrawingEngine.cpp
index b5c425a..90dbb20 100644
--- a/src/servers/app/drawing/DrawingEngine.cpp
+++ b/src/servers/app/drawing/DrawingEngine.cpp
@@ -23,6 +23,7 @@
#include "ServerBitmap.h"
#include "ServerCursor.h"
#include "RenderingBuffer.h"
+#include "Window.h"

#include "drawing_support.h"

@@ -104,6 +105,7 @@ DrawingEngine::DrawingEngine(HWInterface* interface)
:
fPainter(new Painter()),
fGraphicsCard(NULL),
+ fDrawingBuffer(NULL),
fAvailableHWAccleration(0),
fSuspendSyncLevel(0),
fCopyToFront(true)
@@ -181,7 +183,13 @@ 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();
@@ -208,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;
@@ -628,6 +648,23 @@ 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)
{
@@ -900,6 +937,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)) {
@@ -1070,7 +1108,7 @@ DrawingEngine::FillRegion(BRegion& r)
doInSoftware = false;
}
}
-
+
if (doInSoftware
&& (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
&& fPainter->Pattern() == B_SOLID_HIGH
@@ -1400,7 +1438,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;
@@ -1519,6 +1556,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) {
@@ -1560,6 +1598,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;

@@ -1624,3 +1663,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 dd15db2..963f1c5 100644
--- a/src/servers/app/drawing/DrawingEngine.h
+++ b/src/servers/app/drawing/DrawingEngine.h
@@ -27,6 +27,7 @@ class BRegion;

class DrawState;
class Painter;
+class RenderingBuffer;
class ServerBitmap;
class ServerCursor;
class ServerFont;
@@ -42,6 +43,8 @@ public:

// for "changing" hardware
void SetHWInterface(HWInterface*
interface);
+
+ void
SetDrawingBuffer(RenderingBuffer* buffer);

virtual void SetCopyToFrontEnabled(bool enable);
bool CopyToFrontEnabled() const
@@ -98,6 +101,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);
@@ -196,6 +203,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 0893dfb..25ee755 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 9ac646e..88bdcb2 100644
--- a/src/servers/app/drawing/Painter/Painter.cpp
+++ b/src/servers/app/drawing/Painter/Painter.cpp
@@ -1430,7 +1430,7 @@ Painter::DrawBitmap(const ServerBitmap* bitmap, BRect
bitmapRect,

BRect touched = TransformAlignAndClipRect(viewRect);

- if (bitmap && bitmap->IsValid() && touched.IsValid()) {
+ if (bitmap != NULL && bitmap->IsValid() && touched.IsValid()) {
// the native bitmap coordinate system
BRect actualBitmapRect(bitmap->Bounds());

@@ -1455,6 +1455,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 != NULL && 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 -


@@ -1556,7 +1591,7 @@ Painter::_Align(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 166de5b..c98bb22 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -229,6 +229,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..397c434
--- /dev/null
+++ b/src/servers/app/drawing/WindowBuffer.cpp
@@ -0,0 +1,399 @@
+#include <malloc.h>
+#include <syslog.h>
+
+#include <Autolock.h>
+#include <InterfacePrivate.h>
+#include <Screen.h>
+#include <Window.h>
+
+#include "DrawingEngine.h"
+#include "drawing_support.h"
+#include "RapidDebug.h"
+#include "Window.h"
+#include "WindowBuffer.h"
+
+
+WindowBuffer::WindowBuffer(Window* window)
+ :
+ RenderingBuffer(),
+ fWidth((int32)window->Frame().Width()),
+ fHeight((int32)window->Frame().Height()),
+ fOverProvision(30),
+ fBounds(window->Frame()),
+ fWindow(window),
+ fBuffer(NULL)
+{
+ fBounds.OffsetBy(-fBounds.left, -fBounds.top);
+
+ _NewWindowSize(&fWidth, &fHeight);
+
+ if (fBuffer != NULL)
+ memset(fBuffer, 255, BytesPerRow() * Height());
+}
+
+
+WindowBuffer::~WindowBuffer()
+{
+ fLock.Lock();
+ free(fBuffer);
+}
+
+
+// #pragma mark resizing
+
+
+/**
+ * Resizes buffer to accomodate a new window size.
+ */
+void
+WindowBuffer::ResizeTo(int32 width, int32 height)
+{
+ BAutolock _(fLock);
+ int32 newWidth = width;
+ int32 newHeight = height;
+
+ if (_NewWindowSize(&newWidth, &newHeight))
+ _ResizeTo(newWidth, newHeight);
+}
+
+
+// #pragma mark -
+
+
+// Internal conversions not yet needed
+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
+{
+
+}
+
+
+// #pragma mark -
+
+
+bool
+WindowBuffer::Lock()
+{
+ return fLock.Lock();
+}
+
+
+void
+WindowBuffer::Unlock()
+{
+ fLock.Unlock();
+}
+
+
+Window*
+WindowBuffer::GetWindow()
+{
+ return fWindow;
+}
+
+
+// #pragma mark RenderingBuffer
+
+
+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)
+ return fBuffer;
+ else
+ fBuffer = malloc(BytesPerRow() * fHeight);
+
+ // TODO: fail more nicely? Maybe trigger memory cleanup?
+ if (fBuffer == NULL)
+ debugger("WindowBuffer malloc() failed\n");
+
+ return fBuffer;
+}
+
+
+uint32
+WindowBuffer::BytesPerRow() const
+{
+ BAutolock _(fLock);
+ 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 -
+
+
+bool
+WindowBuffer::ClientDrawLock()
+{
+ BAutolock _(fLock);
+ return fClientDrawLock.Lock();
+}
+
+
+void
+WindowBuffer::ClientDrawUnlock()
+{
+ fClientDrawLock.Unlock();
+}
+
+
+bool
+WindowBuffer::CopyToFrontLock()
+{
+ // TODO: do we really care about the return values??
+ if (fLock.Lock() && fClientDrawLock.Lock())
+ return true;
+
_LOG("FAILURE!\nFAILURE!!\tWindowBuffer::CopyToFrontLock()\nFAILURE!\n");
+ return false;
+}
+
+
+void
+WindowBuffer::CopyToFrontUnlock()
+{
+ fClientDrawLock.Unlock();
+}
+
+
+// #pragma mark private
+
+
+/*! 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.
+ */
+void
+WindowBuffer::_ResizeTo(int32 width, int32 height)
+{
+ // TODO: we are currently running within the Desktop thread,
+ // it may be worthwhile to spawn a thread for the copying
+ // and holding a lock so as to allow the Desktop thread to
+ // continue processing. TODO: <<profile-code-path>>
+ _LOGF("_ResizeTo from (%lu, %lu) to (%lu, %lu)\n",
+ fWidth, fHeight, width, height);
+
+ BAutolock _(fLock);
+
+ if (width == fWidth && height == fHeight)
+ return;
+
+ if (fBuffer != NULL) {
+ uint32 bytesPerPixel = 4;
+ uint32 bytesPerRow = bytesPerPixel*width;
+ uint32* destBuffer = (uint32*)malloc(bytesPerRow*height);
+ uint32* 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 sourceWidth = fWidth;
+ int32 srcLen = sourceWidth*bytesPerPixel;
+ int32 destWidth = width;
+ int32 destLen = destWidth*bytesPerPixel;
+ int32 srcHeight = fHeight;
+ int32 xDelta = width - fWidth;
+ int32 xDeltaLen = xDelta * bytesPerPixel;
+ int32 yDelta = height - fHeight;
+ int32 xShrinkDelta= 0;
+
+ // shrinking...
+ if (sourceWidth > width) {
+ xShrinkDelta = sourceWidth - width;
+ sourceWidth = width;
+ srcLen = sourceWidth * bytesPerPixel;
+ 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 += sourceWidth;
+ srcBuffer += sourceWidth + 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 data pointer changed, the drawing engine needs to be updated
so
+ // Painer paints into the new memory location.
+ fWindow->GetDrawingEngine()->SetDrawingBuffer(this);
+}
+
+
+/*! Determine proper buffer dimensions for a given window size.
+ *
+ * This function is responsible for providing over-provisioning in order to
+ * reduce copies when resizing the window as well as providing room for the
+ * Decorator and shadow regions, if applicable. The given width and height
+ * are pointers to 32-bit integers, whose values will be changed to reflect
+ * the size required by _ResizeTo(...).
+ *
+ * @return bool
+ * Returns true if the buffer size will need to change to
accomodate new
+ * window size.
+ */
+bool
+WindowBuffer::_NewWindowSize(int32* width, int32* height)
+{
+ // TODO: make aware of app_server settings:
+ // compositing enabled, decor buffering, shadows enabled
+ // 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;
+
+ 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..1066812
--- /dev/null
+++ b/src/servers/app/drawing/WindowBuffer.h
@@ -0,0 +1,74 @@
+#ifndef WINDOW_BUFFER_H
+#define WINDOW_BUFFER_H
+
+#include <GraphicsDefs.h>
+#include <Locker.h>
+#include <Region.h>
+
+#include "RenderingBuffer.h"
+
+class Window;
+
+class WindowBuffer : public RenderingBuffer{
+ public:
+
WindowBuffer(Window* window);
+ virtual ~WindowBuffer();
+
+ size_t MemoryUsage();
+
+ // New Window size.
+ void ResizeTo(int32 width,
int32 height);
+
+ // 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;
+ void
ConvertFromBuffer(BRegion* region) const;
+
+ 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;
+ virtual uint32 Width() const;
+ virtual uint32 Height() const;
+
+ size_t
ReduceMemoryFootprint(bool max = false);
+ // Returns memory saved by operation.
+
+ // Lock for client drawing
+ bool ClientDrawLock();
+ void ClientDrawUnlock();
+
+ bool CopyToFrontLock();

[ *** diff truncated: 20 lines dropped *** ]


############################################################################

Commit: 352ca7930278e9ecd856873080691798467fe9c9
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Wed Mar 18 18:37:50 2015 UTC

Rebase remnants removal

----------------------------------------------------------------------------

############################################################################

Commit: 12875a54fcf7cdf743ec4fd1b96dd93f1b8642b3
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Wed Mar 18 20:05:39 2015 UTC

Style cleanup

(Thanks Axel!)

----------------------------------------------------------------------------

############################################################################

Commit: ede329f4214bdc57b10e60ea5ff76a5bdb7ce3d0
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Fri Mar 20 19:37:09 2015 UTC

Place saver

Create dirty branch to make quick saves that are more volatile than
CAP-volatile...

yeah, seriously!

----------------------------------------------------------------------------

############################################################################

Commit: bc001f2cfbb2ff866d1b912c972488cfe34d7a42
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Fri Mar 20 19:40:31 2015 UTC

Pick up some dirty stragglers

----------------------------------------------------------------------------

############################################################################

Commit: 7acd54b0800b0ef967e9d92d988286e1007e75ba
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Sat Mar 21 06:01:16 2015 UTC

Moving along

Properly separate Window and CompositeWindow, implement many little
bits in that regard to handle the difference between a dirtregion
and a region which genuinely needs to be redrawn by the client.

Included a WeakLazyLocker - completely untested, but similar to
something else I've used for quite some time, so it should be OK.
Hey, there's a reason I call this the 'dirty' branch!

----------------------------------------------------------------------------

############################################################################

Commit: 2ba1a2d470197c19cd69736202ab9401bcfa7b1e
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Sat Mar 21 19:15:24 2015 UTC

Move coordinate conversions & complete renaming

OffscreenServerWindow had the coordinate conversion methods for
some reason, they belong in OffscreenWindow.

Also completed renaming ConvertViewToDrawing to ConvertWindowToDrawing,
which is more accurate.

----------------------------------------------------------------------------

############################################################################

Commit: 422d08f0a6e83ca708f3aedca68da0a6edbd1bc2
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Sat Mar 21 19:32:51 2015 UTC

WeakLazyLocker

Try to get the lock when it seems safe to do so in SetLazyServerLock()

----------------------------------------------------------------------------

############################################################################

Commit: e083c1752c75f7c85d090dc51e381e312d2fed79
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Sun Mar 22 22:33:02 2015 UTC

Initial CompositeEngine (v2)

Now overloading AccelerantHWInterface and giving each window its own
CompositeWindowHWInterface which will need to interact with a dedicated
type of accelerant for client-draw acceleration.

Dozens of other small changes.

This is the dirty branch, this stuff is full of errors ;-)

----------------------------------------------------------------------------

############################################################################

Commit: 1bdb582bbf295ee1e62249051711a91b359ed45a
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Mon Mar 23 03:19:20 2015 UTC

Compiles, links

A great deal more fleshing out. Finally compiles and links, but the basic
control structure is still incomplete.

This part is working out smoothly, I should be able to bring in more
of the non-public code here and there as time progresses.

----------------------------------------------------------------------------

############################################################################

Commit: 0f8b557184e32ceb111c025aa4ca6b26ae8c1009
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Mon Mar 23 05:02:40 2015 UTC

Fix Cyclic Call

Don't you just hate it when you forget to reference the derive class's
version of a function call you overloaded and cause a KDL?

I sure do.

----------------------------------------------------------------------------

############################################################################

Commit: 24f08db73adbfa28b5330e3047568b153c4b7696
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Mon Mar 23 17:03:08 2015 UTC

Style cleanup

----------------------------------------------------------------------------

############################################################################

Commit: 7ec4cb13105d00509a91e0be599d45fea8a40d5e
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Mon Mar 23 17:13:44 2015 UTC

Fix CompositeHWInterface

----------------------------------------------------------------------------

############################################################################

Commit: 567469a8bb5c15c5492c2fb1669287129db9c2da
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Tue Mar 24 17:16:00 2015 UTC

Modify RapidDebug

----------------------------------------------------------------------------

############################################################################

Commit: ca18eeef551a58fbf416342911ca03c3cc429b40
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Wed Mar 25 01:18:19 2015 UTC

Client-Server Protocol

Define and implement basic interface for controlling compositing
on a live system.

Added in system bin 'capset' to provide command-line access to features
as well as for testing purposes.

More to go!

----------------------------------------------------------------------------

############################################################################

Commit: 81ee88ec1a430fbaf60ce4753079ed13b686210f
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Wed Mar 25 04:43:06 2015 UTC

Initial Communications

Can now pull and set the state. Though, you seriously don't want
to enable compositing right now. Things, as expected, go a little
kooky.

----------------------------------------------------------------------------

############################################################################

Commit: 76e43c469e69673678e9d8012cd56b3e734ff8d9
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Thu Mar 26 06:15:11 2015 UTC

Minor tweaks

Prevent CompositeWindow from setting itself to compositing mode for now,
Add a client auto-locker for WeakLazyLocker.
Fixed a race condition in WeakLazyLocker.
Minor update to set state handling

----------------------------------------------------------------------------

############################################################################

Commit: a3821005e613c3ffa72dd45dc1f6fc67ffd54f5c
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()

----------------------------------------------------------------------------

############################################################################

Commit: f75cde3bbb2725ac62d8a4b7186d34a3362ed509
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Thu Mar 26 19:34:16 2015 UTC

Initialized buffers to NULL

----------------------------------------------------------------------------

############################################################################

Commit: 835a04684937d84889019ff8334738d784f015ca
Author: looncraz <looncraz@xxxxxxxxxxxx>
Date: Fri Mar 27 18:47:42 2015 UTC

Get rid of spurios locks

Access is mostly serialized and locking just adds overhead and the
potential for deadlocks, so getting rid of it wherever possible.

Also modified (temporarily) the bootscript to launch the app_server
from the root of the boot drive for testing.

Almost to the point where I can replace the app_server on the running
system and restart rather than runninbuilds on one virtual machine
and testing on another

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] BRANCH looncraz-github.CAP-dirty [835a04684937] in src: servers/app/drawing/interface/local servers/app servers/app/drawing bin/capset - looncraz-github . CAP-dirty