app_server: Some cleanup of the new clipping code.
* Fixed some coding style issues and use regular pointers like everywhere else in app_server code. * Moved _RenderPicture() from View to AlphaMask.
This commit is contained in:
@@ -1,16 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014, Haiku, Inc.
|
* Copyright 2014, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Adrien Destugues <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "AlphaMask.h"
|
#include "AlphaMask.h"
|
||||||
|
|
||||||
|
#include "BitmapHWInterface.h"
|
||||||
|
#include "BitmapManager.h"
|
||||||
|
#include "DrawingEngine.h"
|
||||||
#include "ServerBitmap.h"
|
#include "ServerBitmap.h"
|
||||||
#include "View.h"
|
#include "View.h"
|
||||||
|
|
||||||
|
|
||||||
AlphaMask::AlphaMask(View& view, ServerPicture& picture, bool inverse,
|
AlphaMask::AlphaMask(View* view, ServerPicture* picture, bool inverse,
|
||||||
BPoint origin)
|
BPoint origin)
|
||||||
:
|
:
|
||||||
fPicture(picture),
|
fPicture(picture),
|
||||||
@@ -22,13 +28,13 @@ AlphaMask::AlphaMask(View& view, ServerPicture& picture, bool inverse,
|
|||||||
fCachedMask(),
|
fCachedMask(),
|
||||||
fScanline(fCachedMask)
|
fScanline(fCachedMask)
|
||||||
{
|
{
|
||||||
fPicture.AcquireReference();
|
fPicture->AcquireReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AlphaMask::~AlphaMask()
|
AlphaMask::~AlphaMask()
|
||||||
{
|
{
|
||||||
fPicture.ReleaseReference();
|
fPicture->ReleaseReference();
|
||||||
if (fCachedBitmap)
|
if (fCachedBitmap)
|
||||||
fCachedBitmap->ReleaseReference();
|
fCachedBitmap->ReleaseReference();
|
||||||
}
|
}
|
||||||
@@ -37,23 +43,87 @@ AlphaMask::~AlphaMask()
|
|||||||
scanline_unpacked_masked_type*
|
scanline_unpacked_masked_type*
|
||||||
AlphaMask::Generate()
|
AlphaMask::Generate()
|
||||||
{
|
{
|
||||||
// If rendering the picture fails, we will draw without any clipping.
|
// if (fCachedBitmap != NULL) {
|
||||||
ServerBitmap* bitmap = fView._RenderPicture(&fPicture, fInverse);
|
// // TODO: See if cached bitmap can actually be used. Don't use it
|
||||||
if (!bitmap)
|
// // when view scrolling offset has changed, for example. Generate()
|
||||||
return NULL;
|
// // could be passed a current offset
|
||||||
|
// return &fScanline;
|
||||||
|
// }
|
||||||
|
|
||||||
// FIXME actually use the cached bitmap whenever possible, instead of
|
if (fCachedBitmap != NULL)
|
||||||
// rendering the BPicture again and again.
|
|
||||||
if (fCachedBitmap)
|
|
||||||
fCachedBitmap->ReleaseReference();
|
fCachedBitmap->ReleaseReference();
|
||||||
|
|
||||||
|
// If rendering the picture fails, we will draw without any clipping.
|
||||||
|
ServerBitmap* bitmap = _RenderPicture(fPicture, fInverse);
|
||||||
|
if (bitmap == NULL) {
|
||||||
|
fCachedBitmap = NULL;
|
||||||
|
fBuffer.attach(NULL, 0, 0, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fCachedBitmap = bitmap;
|
fCachedBitmap = bitmap;
|
||||||
|
|
||||||
fBuffer.attach(fCachedBitmap->Bits(), fCachedBitmap->Width(),
|
fBuffer.attach(fCachedBitmap->Bits(), fCachedBitmap->Width(),
|
||||||
fCachedBitmap->Height(), fCachedBitmap->BytesPerRow());
|
fCachedBitmap->Height(), fCachedBitmap->BytesPerRow());
|
||||||
|
|
||||||
BPoint offset(B_ORIGIN);
|
BPoint offset(B_ORIGIN);
|
||||||
fView.ConvertToScreen(&offset);
|
fView->ConvertToScreen(&offset);
|
||||||
|
|
||||||
fCachedMask.attach(fBuffer, offset.x + fOrigin.x, offset.y + fOrigin.y,
|
fCachedMask.attach(fBuffer, offset.x + fOrigin.x, offset.y + fOrigin.y,
|
||||||
fInverse ? 255 : 0);
|
fInverse ? 255 : 0);
|
||||||
|
|
||||||
return &fScanline;
|
return &fScanline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ServerBitmap*
|
||||||
|
AlphaMask::_RenderPicture(ServerPicture* picture, bool inverse) const
|
||||||
|
{
|
||||||
|
BRect bounds(fView->Bounds());
|
||||||
|
|
||||||
|
// TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
|
||||||
|
// color space, so we use 300% more memory than needed.
|
||||||
|
UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, B_RGBA32,
|
||||||
|
0);
|
||||||
|
if (bitmap == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Clear the bitmap with the transparent color
|
||||||
|
memset(bitmap->Bits(), 0, bitmap->BitsLength());
|
||||||
|
|
||||||
|
// Render the picture to the bitmap
|
||||||
|
BitmapHWInterface interface(bitmap);
|
||||||
|
DrawingEngine* engine = interface.CreateDrawingEngine();
|
||||||
|
if (engine == NULL) {
|
||||||
|
delete bitmap;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the current state of the client view, so we draw with the right
|
||||||
|
// font, color and everything
|
||||||
|
engine->SetDrawState(fView->CurrentState());
|
||||||
|
OffscreenContext context(engine);
|
||||||
|
if (engine->LockParallelAccess()) {
|
||||||
|
// FIXME ConstrainClippingRegion docs says passing NULL disables
|
||||||
|
// all clipping. This doesn't work and will crash in Painter.
|
||||||
|
BRegion clipping;
|
||||||
|
clipping.Include(bounds);
|
||||||
|
engine->ConstrainClippingRegion(&clipping);
|
||||||
|
picture->Play(&context);
|
||||||
|
engine->UnlockParallelAccess();
|
||||||
|
}
|
||||||
|
delete engine;
|
||||||
|
|
||||||
|
if (!inverse)
|
||||||
|
return bitmap;
|
||||||
|
|
||||||
|
// Compute the inverse of our bitmap. There probably is a better way.
|
||||||
|
uint32 size = bitmap->BitsLength();
|
||||||
|
uint8* bits = (uint8*)bitmap->Bits();
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < size; i++)
|
||||||
|
bits[i] = 255 - bits[i];
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-18
@@ -17,26 +17,30 @@
|
|||||||
class ServerBitmap;
|
class ServerBitmap;
|
||||||
|
|
||||||
|
|
||||||
class AlphaMask
|
class AlphaMask {
|
||||||
{
|
public:
|
||||||
public:
|
AlphaMask(View* view, ServerPicture* mask,
|
||||||
AlphaMask(View& view,
|
bool inverse, BPoint origin);
|
||||||
ServerPicture& mask, bool inverse,
|
~AlphaMask();
|
||||||
BPoint origin);
|
|
||||||
~AlphaMask();
|
|
||||||
scanline_unpacked_masked_type* Generate();
|
|
||||||
|
|
||||||
private:
|
scanline_unpacked_masked_type* Generate();
|
||||||
ServerPicture& fPicture;
|
|
||||||
const bool fInverse;
|
|
||||||
const BPoint fOrigin;
|
|
||||||
View& fView;
|
|
||||||
|
|
||||||
ServerBitmap* fCachedBitmap;
|
private:
|
||||||
agg::rendering_buffer fBuffer;
|
ServerBitmap* _RenderPicture(ServerPicture* picture,
|
||||||
agg::clipped_alpha_mask fCachedMask;
|
bool inverse) const;
|
||||||
scanline_unpacked_masked_type fScanline;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
ServerPicture* fPicture;
|
||||||
|
const bool fInverse;
|
||||||
|
BPoint fOrigin;
|
||||||
|
View* fView;
|
||||||
|
|
||||||
|
ServerBitmap* fCachedBitmap;
|
||||||
|
agg::rendering_buffer fBuffer;
|
||||||
|
agg::clipped_alpha_mask fCachedMask;
|
||||||
|
scanline_unpacked_masked_type fScanline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif // ALPHA_MASK_H
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "AlphaMask.h"
|
#include "AlphaMask.h"
|
||||||
#include "BitmapHWInterface.h"
|
|
||||||
#include "BitmapManager.h"
|
|
||||||
#include "Desktop.h"
|
#include "Desktop.h"
|
||||||
#include "DrawingEngine.h"
|
#include "DrawingEngine.h"
|
||||||
#include "DrawState.h"
|
#include "DrawState.h"
|
||||||
@@ -1596,79 +1594,13 @@ View::SetAlphaMask(ServerPicture* picture, bool inverse, BPoint origin)
|
|||||||
|
|
||||||
delete fAlphaMask;
|
delete fAlphaMask;
|
||||||
if (picture != NULL) {
|
if (picture != NULL) {
|
||||||
fAlphaMask = new(std::nothrow) AlphaMask(*this, *picture, inverse,
|
fAlphaMask = new(std::nothrow) AlphaMask(this, picture, inverse,
|
||||||
origin);
|
origin);
|
||||||
} else
|
} else
|
||||||
fAlphaMask = NULL;
|
fAlphaMask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ServerBitmap*
|
|
||||||
View::_RenderPicture(ServerPicture* picture, bool inverse)
|
|
||||||
{
|
|
||||||
BRect bounds(Bounds());
|
|
||||||
|
|
||||||
// TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
|
|
||||||
// color space, so we use 300% more memory than needed.
|
|
||||||
UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, B_RGBA32,
|
|
||||||
0);
|
|
||||||
if (bitmap == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* TODO stippi says we could use OffscreenWindow to do this, but there
|
|
||||||
* doesn't seem to be a way to create a View without a BView on
|
|
||||||
* application side (the constructor wants a token).
|
|
||||||
* This would be better, as it would avoid the DrawingContext abstraction
|
|
||||||
* above View and OffscreenContext and allow for inlining more methods.
|
|
||||||
*/
|
|
||||||
OffscreenWindow window(bitmap, "ClipToPicture", Window());
|
|
||||||
View view(bounds, IntPoint(0, 0), "ClipToPicture");
|
|
||||||
window->SetTopView(view);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Clear the bitmap with the transparent color
|
|
||||||
memset(bitmap->Bits(), 0, bitmap->BitsLength());
|
|
||||||
|
|
||||||
// Render the picture to the bitmap
|
|
||||||
BitmapHWInterface interface(bitmap);
|
|
||||||
DrawingEngine* engine = interface.CreateDrawingEngine();
|
|
||||||
if (engine == NULL) {
|
|
||||||
delete bitmap;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the current state of the client view, so we draw with the right
|
|
||||||
// font, color and everything
|
|
||||||
engine->SetDrawState(CurrentState());
|
|
||||||
OffscreenContext context(engine);
|
|
||||||
if (engine->LockParallelAccess())
|
|
||||||
{
|
|
||||||
// FIXME ConstrainClippingRegion docs says passing NULL disables
|
|
||||||
// all clipping. This doesn't work and will crash in Painter.
|
|
||||||
BRegion clipping;
|
|
||||||
clipping.Include(bounds);
|
|
||||||
engine->ConstrainClippingRegion(&clipping);
|
|
||||||
picture->Play(&context);
|
|
||||||
engine->UnlockParallelAccess();
|
|
||||||
}
|
|
||||||
delete engine;
|
|
||||||
|
|
||||||
if (!inverse)
|
|
||||||
return bitmap;
|
|
||||||
|
|
||||||
// Compute the inverse of our bitmap. There probably is a better way.
|
|
||||||
uint32 size = bitmap->BitsLength();
|
|
||||||
uint8* bits = (uint8*)bitmap->Bits();
|
|
||||||
|
|
||||||
for(uint32 i = 0; i < size; i++)
|
|
||||||
bits[i] = 255 - bits[i];
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BRegion&
|
BRegion&
|
||||||
View::_ScreenClipping(BRegion* windowContentClipping, bool force) const
|
View::_ScreenClipping(BRegion* windowContentClipping, bool force) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class ServerPicture;
|
|||||||
class BGradient;
|
class BGradient;
|
||||||
|
|
||||||
class View: public DrawingContext {
|
class View: public DrawingContext {
|
||||||
public:
|
public:
|
||||||
View(IntRect frame, IntPoint scrollingOffset,
|
View(IntRect frame, IntPoint scrollingOffset,
|
||||||
const char* name, int32 token,
|
const char* name, int32 token,
|
||||||
uint32 resizeMode, uint32 flags);
|
uint32 resizeMode, uint32 flags);
|
||||||
@@ -232,10 +232,7 @@ class View: public DrawingContext {
|
|||||||
int32 level = 0);
|
int32 level = 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AlphaMask;
|
|
||||||
ServerBitmap* _RenderPicture(ServerPicture* picture,
|
|
||||||
bool inverse);
|
|
||||||
BRegion& _ScreenClipping(BRegion* windowContentClipping,
|
BRegion& _ScreenClipping(BRegion* windowContentClipping,
|
||||||
bool force = false) const;
|
bool force = false) const;
|
||||||
void _MoveScreenClipping(int32 x, int32 y,
|
void _MoveScreenClipping(int32 x, int32 y,
|
||||||
|
|||||||
Reference in New Issue
Block a user