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 BObjectList<BPicture> sPictureList;
static mutex sPictureListLock = MUTEX_INITIALIZER("BPicture list"); static recursive_lock sPictureListLock = RECURSIVE_LOCK_INITIALIZER("BPicture list");
void void
reconnect_pictures_to_app_server() reconnect_pictures_to_app_server()
{ {
MutexLocker _(sPictureListLock); RecursiveLocker _(sPictureListLock);
for (int32 i = 0; i < sPictureList.CountItems(); i++) { for (int32 i = 0; i < sPictureList.CountItems(); i++) {
BPicture::Private picture(sPictureList.ItemAt(i)); BPicture::Private picture(sPictureList.ItemAt(i));
picture.ReconnectToAppServer(); picture.ReconnectToAppServer();
@@ -215,14 +215,14 @@ BPicture::_InitData()
fExtent = new (std::nothrow) _BPictureExtent_; fExtent = new (std::nothrow) _BPictureExtent_;
MutexLocker _(sPictureListLock); RecursiveLocker _(sPictureListLock);
sPictureList.AddItem(this); sPictureList.AddItem(this);
} }
BPicture::~BPicture() BPicture::~BPicture()
{ {
MutexLocker _(sPictureListLock); RecursiveLocker _(sPictureListLock);
sPictureList.RemoveItem(this, false); sPictureList.RemoveItem(this, false);
_DisposeData(); _DisposeData();
} }
-3
View File
@@ -73,7 +73,6 @@ public:
void BlendLayer(Layer* layer); void BlendLayer(Layer* layer);
virtual DrawingEngine* GetDrawingEngine() const = 0; virtual DrawingEngine* GetDrawingEngine() const = 0;
virtual ServerPicture* GetPicture(int32 token) const = 0;
virtual void RebuildClipping(bool deep) = 0; virtual void RebuildClipping(bool deep) = 0;
virtual void ResyncDrawState() {}; virtual void ResyncDrawState() {};
virtual void UpdateCurrentDrawingRegion() {}; virtual void UpdateCurrentDrawingRegion() {};
@@ -101,8 +100,6 @@ public:
virtual void RebuildClipping(bool deep) { /* TODO */ } virtual void RebuildClipping(bool deep) { /* TODO */ }
virtual void ResyncDrawState(); virtual void ResyncDrawState();
virtual void UpdateCurrentDrawingRegion(); virtual void UpdateCurrentDrawingRegion();
virtual ServerPicture* GetPicture(int32 token) const
{ /* TODO */ return NULL; }
virtual IntRect Bounds() const; virtual IntRect Bounds() const;
protected: protected:
+16 -10
View File
@@ -239,7 +239,7 @@ ShapePainter::Draw(BRect frame, bool filled)
class CanvasCallbacks: public BPrivate::PicturePlayerCallbacks { class CanvasCallbacks: public BPrivate::PicturePlayerCallbacks {
public: public:
CanvasCallbacks(Canvas* const canvas); CanvasCallbacks(Canvas* const canvas, BObjectList<ServerPicture>& pictures);
virtual void MovePenBy(const BPoint& where); virtual void MovePenBy(const BPoint& where);
virtual void StrokeLine(const BPoint& start, const BPoint& end); virtual void StrokeLine(const BPoint& start, const BPoint& end);
@@ -309,12 +309,14 @@ public:
private: private:
Canvas* const fCanvas; 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 void
CanvasCallbacks::DrawPicture(const BPoint& where, int32 token) CanvasCallbacks::DrawPicture(const BPoint& where, int32 token)
{ {
BReference<ServerPicture> picture(fCanvas->GetPicture(token), true); BReference<ServerPicture> picture(fPictures.ItemAt(token), false);
if (picture != NULL) { if (picture != NULL) {
fCanvas->PushState(); fCanvas->PushState();
fCanvas->SetDrawingOrigin(where); fCanvas->SetDrawingOrigin(where);
@@ -690,7 +692,7 @@ void
CanvasCallbacks::ClipToPicture(int32 pictureToken, const BPoint& where, CanvasCallbacks::ClipToPicture(int32 pictureToken, const BPoint& where,
bool clipToInverse) bool clipToInverse)
{ {
BReference<ServerPicture> picture(fCanvas->GetPicture(pictureToken), true); BReference<ServerPicture> picture(fPictures.ItemAt(pictureToken), false);
if (picture == NULL) if (picture == NULL)
return; return;
BReference<AlphaMask> mask(new(std::nothrow) PictureAlphaMask(fCanvas->GetAlphaMask(), BReference<AlphaMask> mask(new(std::nothrow) PictureAlphaMask(fCanvas->GetAlphaMask(),
@@ -1246,7 +1248,7 @@ ServerPicture::Play(Canvas* target)
if (mallocIO == NULL) if (mallocIO == NULL)
return; return;
CanvasCallbacks callbacks(target); CanvasCallbacks callbacks(target, *fPictures.Get());
BPrivate::PicturePlayer player(mallocIO->Buffer(), BPrivate::PicturePlayer player(mallocIO->Buffer(),
mallocIO->BufferLength(), PictureList::Private(fPictures.Get()).AsBList()); mallocIO->BufferLength(), PictureList::Private(fPictures.Get()).AsBList());
@@ -1283,17 +1285,21 @@ ServerPicture::AppendPicture(ServerPicture* picture)
} }
bool int32
ServerPicture::NestPicture(ServerPicture* picture) ServerPicture::NestPicture(ServerPicture* picture)
{ {
if (!fPictures.IsSet()) if (!fPictures.IsSet())
fPictures.SetTo(new(std::nothrow) PictureList); fPictures.SetTo(new(std::nothrow) PictureList);
if (!fPictures.IsSet() || !fPictures->AddItem(picture)) if (!fPictures.IsSet())
return false; return -1;
int32 index = fPictures->CountItems();
if (!fPictures->AddItem(picture))
return -1;
picture->AcquireReference(); picture->AcquireReference();
return true; return index;
} }
+1 -1
View File
@@ -60,7 +60,7 @@ public:
ServerPicture* PopPicture(); ServerPicture* PopPicture();
void AppendPicture(ServerPicture* picture); void AppendPicture(ServerPicture* picture);
bool NestPicture(ServerPicture* picture); int32 NestPicture(ServerPicture* picture);
off_t DataLength() const; 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 // We need to make a copy of the picture, since it can
// change after it has been drawn // change after it has been drawn
BReference<ServerPicture> copy(App()->CreatePicture(pictureToDraw), true); BReference<ServerPicture> copy(App()->CreatePicture(pictureToDraw), true);
picture->NestPicture(copy); int32 subPictureIndex = picture->NestPicture(copy);
picture->WriteDrawPicture(where, copy->Token()); if (subPictureIndex >= 0)
picture->WriteDrawPicture(where, subPictureIndex);
} }
} }
break; break;
@@ -4063,8 +4064,9 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
// We need to make a copy of the picture, since it can // We need to make a copy of the picture, since it can
// change after it has been drawn // change after it has been drawn
BReference<ServerPicture> copy(App()->CreatePicture(pictureToClip), true); BReference<ServerPicture> copy(App()->CreatePicture(pictureToClip), true);
picture->NestPicture(copy); int32 subPictureIndex = picture->NestPicture(copy);
picture->WriteClipToPicture(copy->Token(), where, inverse); if (subPictureIndex >= 0)
picture->WriteClipToPicture(subPictureIndex, where, inverse);
} }
break; break;
} }