BPicture: fix subpicture token storage

Picture token written for `BView::DrawPicture` and
`BView::ClipTo[Inverse]Picture` should be zero-based index in
subpictures array, not global app_server BPicture token.

Part of #1133.

Change-Id: I2a544aefb343650e8bad58c5d297f7b9d5d1dbb5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10575
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
X512
2026-03-24 14:33:50 +00:00
committed by waddlesplash
parent 90ac9e6538
commit 0a40b3a1ce
5 changed files with 27 additions and 22 deletions
+4 -4
View File
@@ -33,13 +33,13 @@
static BObjectList<BPicture> sPictureList;
static mutex sPictureListLock = MUTEX_INITIALIZER("BPicture list");
static recursive_lock sPictureListLock = RECURSIVE_LOCK_INITIALIZER("BPicture list");
void
reconnect_pictures_to_app_server()
{
MutexLocker _(sPictureListLock);
RecursiveLocker _(sPictureListLock);
for (int32 i = 0; i < sPictureList.CountItems(); i++) {
BPicture::Private picture(sPictureList.ItemAt(i));
picture.ReconnectToAppServer();
@@ -215,14 +215,14 @@ BPicture::_InitData()
fExtent = new (std::nothrow) _BPictureExtent_;
MutexLocker _(sPictureListLock);
RecursiveLocker _(sPictureListLock);
sPictureList.AddItem(this);
}
BPicture::~BPicture()
{
MutexLocker _(sPictureListLock);
RecursiveLocker _(sPictureListLock);
sPictureList.RemoveItem(this, false);
_DisposeData();
}
-3
View File
@@ -73,7 +73,6 @@ public:
void BlendLayer(Layer* layer);
virtual DrawingEngine* GetDrawingEngine() const = 0;
virtual ServerPicture* GetPicture(int32 token) const = 0;
virtual void RebuildClipping(bool deep) = 0;
virtual void ResyncDrawState() {};
virtual void UpdateCurrentDrawingRegion() {};
@@ -101,8 +100,6 @@ public:
virtual void RebuildClipping(bool deep) { /* TODO */ }
virtual void ResyncDrawState();
virtual void UpdateCurrentDrawingRegion();
virtual ServerPicture* GetPicture(int32 token) const
{ /* TODO */ return NULL; }
virtual IntRect Bounds() const;
protected:
+16 -10
View File
@@ -239,7 +239,7 @@ ShapePainter::Draw(BRect frame, bool filled)
class CanvasCallbacks: public BPrivate::PicturePlayerCallbacks {
public:
CanvasCallbacks(Canvas* const canvas);
CanvasCallbacks(Canvas* const canvas, BObjectList<ServerPicture>& pictures);
virtual void MovePenBy(const BPoint& where);
virtual void StrokeLine(const BPoint& start, const BPoint& end);
@@ -309,12 +309,14 @@ public:
private:
Canvas* const fCanvas;
BObjectList<ServerPicture>& fPictures;
};
CanvasCallbacks::CanvasCallbacks(Canvas* const canvas)
CanvasCallbacks::CanvasCallbacks(Canvas* const canvas, BObjectList<ServerPicture>& pictures)
:
fCanvas(canvas)
fCanvas(canvas),
fPictures(pictures)
{
}
@@ -655,7 +657,7 @@ CanvasCallbacks::DrawPixels(const BRect& src, const BRect& _dest, uint32 width,
void
CanvasCallbacks::DrawPicture(const BPoint& where, int32 token)
{
BReference<ServerPicture> picture(fCanvas->GetPicture(token), true);
BReference<ServerPicture> picture(fPictures.ItemAt(token), false);
if (picture != NULL) {
fCanvas->PushState();
fCanvas->SetDrawingOrigin(where);
@@ -690,7 +692,7 @@ void
CanvasCallbacks::ClipToPicture(int32 pictureToken, const BPoint& where,
bool clipToInverse)
{
BReference<ServerPicture> picture(fCanvas->GetPicture(pictureToken), true);
BReference<ServerPicture> picture(fPictures.ItemAt(pictureToken), false);
if (picture == NULL)
return;
BReference<AlphaMask> mask(new(std::nothrow) PictureAlphaMask(fCanvas->GetAlphaMask(),
@@ -1246,7 +1248,7 @@ ServerPicture::Play(Canvas* target)
if (mallocIO == NULL)
return;
CanvasCallbacks callbacks(target);
CanvasCallbacks callbacks(target, *fPictures.Get());
BPrivate::PicturePlayer player(mallocIO->Buffer(),
mallocIO->BufferLength(), PictureList::Private(fPictures.Get()).AsBList());
@@ -1283,17 +1285,21 @@ ServerPicture::AppendPicture(ServerPicture* picture)
}
bool
int32
ServerPicture::NestPicture(ServerPicture* picture)
{
if (!fPictures.IsSet())
fPictures.SetTo(new(std::nothrow) PictureList);
if (!fPictures.IsSet() || !fPictures->AddItem(picture))
return false;
if (!fPictures.IsSet())
return -1;
int32 index = fPictures->CountItems();
if (!fPictures->AddItem(picture))
return -1;
picture->AcquireReference();
return true;
return index;
}
+1 -1
View File
@@ -60,7 +60,7 @@ public:
ServerPicture* PopPicture();
void AppendPicture(ServerPicture* picture);
bool NestPicture(ServerPicture* picture);
int32 NestPicture(ServerPicture* picture);
off_t DataLength() const;
+6 -4
View File
@@ -4012,8 +4012,9 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
// We need to make a copy of the picture, since it can
// change after it has been drawn
BReference<ServerPicture> copy(App()->CreatePicture(pictureToDraw), true);
picture->NestPicture(copy);
picture->WriteDrawPicture(where, copy->Token());
int32 subPictureIndex = picture->NestPicture(copy);
if (subPictureIndex >= 0)
picture->WriteDrawPicture(where, subPictureIndex);
}
}
break;
@@ -4063,8 +4064,9 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
// We need to make a copy of the picture, since it can
// change after it has been drawn
BReference<ServerPicture> copy(App()->CreatePicture(pictureToClip), true);
picture->NestPicture(copy);
picture->WriteClipToPicture(copy->Token(), where, inverse);
int32 subPictureIndex = picture->NestPicture(copy);
if (subPictureIndex >= 0)
picture->WriteClipToPicture(subPictureIndex, where, inverse);
}
break;
}