Added B_BITMAP_NO_SERVER_LINK to the BBitmap flags. It constructs a BBitmap without a server link, which consequently cannot be drawn by the app_server, but which is nevertheless very useful. It essentially does the same thing as RUN_WITHOUT_APP_SERVER. I also added a CleanUp() function and moved the cleanup code from InitObject() there. CleanUp() is now called in the destructor, which means that the app_server now knows when to free the server side bitmap.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12814 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-05-25 18:10:20 +00:00
parent 7c5f224338
commit 85b226041a
2 changed files with 141 additions and 142 deletions

View File

@ -1,23 +1,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Distributed under the terms of the MIT license.
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// //
// File Name: Bitmap.h // File Name: Bitmap.h
// Author: Ingo Weinhold (bonefish@users.sf.net) // Author: Ingo Weinhold (bonefish@users.sf.net)
@ -42,7 +26,8 @@ enum {
B_BITMAP_IS_CONTIGUOUS = 0x00000010 | B_BITMAP_IS_LOCKED, B_BITMAP_IS_CONTIGUOUS = 0x00000010 | B_BITMAP_IS_LOCKED,
B_BITMAP_IS_OFFSCREEN = 0x00000020, B_BITMAP_IS_OFFSCREEN = 0x00000020,
B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN, B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN,
B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080 B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080,
B_BITMAP_NO_SERVER_LINK = 0x00000100
}; };
#define B_ANY_BYTES_PER_ROW -1 #define B_ANY_BYTES_PER_ROW -1
@ -120,6 +105,8 @@ private:
int32 get_server_token() const; int32 get_server_token() const;
void InitObject(BRect bounds, color_space colorSpace, uint32 flags, void InitObject(BRect bounds, color_space colorSpace, uint32 flags,
int32 bytesPerRow, screen_id screenID); int32 bytesPerRow, screen_id screenID);
void CleanUp();
void AssertPtr(); void AssertPtr();
void *fBasePtr; void *fBasePtr;

View File

@ -1,27 +1,12 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2004, OpenBeOS // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Distributed under the terms of the MIT license.
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// //
// File Name: Bitmap.cpp // File Name: Bitmap.cpp
// Author: Ingo Weinhold (bonefish@users.sf.net) // Author: Ingo Weinhold (bonefish@users.sf.net)
// DarkWyrm <bpmagic@columbus.rr.com> // DarkWyrm <bpmagic@columbus.rr.com>
// Stephan Aßmus <superstippi@gmx.de>
// Description: BBitmap objects represent off-screen windows that // Description: BBitmap objects represent off-screen windows that
// contain bitmap data. // contain bitmap data.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -825,12 +810,7 @@ BBitmap::BBitmap(const BBitmap *source, bool acceptsViews,
*/ */
BBitmap::~BBitmap() BBitmap::~BBitmap()
{ {
// TODO: don't free fBasePtr, as it's owned by the app_server CleanUp();
// should probably decrement an associated reference count, though,
// so the app_server knows this bitmap isn't used anymore
#ifdef RUN_WITHOUT_APP_SERVER
free(fBasePtr);
#endif // RUN_WITHOUT_APP_SERVER
} }
// unarchiving constructor // unarchiving constructor
@ -2226,40 +2206,21 @@ void
BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags, BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
int32 bytesPerRow, screen_id screenID) int32 bytesPerRow, screen_id screenID)
{ {
//printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n",
// bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow);
// TODO: Hanlde setting up the offscreen window if we're such a bitmap!
// TODO: Should we handle rounding of the "bounds" here? How does R5 behave?
status_t error = B_OK; status_t error = B_OK;
#ifndef RUN_WITHOUT_APP_SERVER
BPrivate::BAppServerLink link;
#endif // RUN_WITHOUT_APP_SERVER
// clean up
if (fBasePtr) {
#ifdef RUN_WITHOUT_APP_SERVER #ifdef RUN_WITHOUT_APP_SERVER
free(fBasePtr); flags |= B_BITMAP_NO_SERVER_LINK;
#endif // RUN_WITHOUT_APP_SERVER #endif // RUN_WITHOUT_APP_SERVER
fBasePtr = NULL;
#ifndef RUN_WITHOUT_APP_SERVER CleanUp();
// AS_DELETE_BITMAP:
// Attached Data:
// 1) int32 server token
// Reply Code: SERVER_TRUE if successful,
// SERVER_FALSE if the buffer was already deleted
// Reply Data:
// none
// status_t freestat;
int32 code = SERVER_FALSE;
link.StartMessage(AS_DELETE_BITMAP);
link.Attach<int32>(fServerToken);
error=link.FlushWithReply(&code);
if(code==SERVER_FALSE)
error=B_NO_MEMORY;
fBasePtr=NULL;
fArea=-1;
fServerToken=-1;
#endif // RUN_WITHOUT_APP_SERVER
}
// check params // check params
if (!bounds.IsValid() || !is_supported(colorSpace)) if (!bounds.IsValid() || !is_supported(colorSpace))
error = B_BAD_VALUE; error = B_BAD_VALUE;
@ -2268,93 +2229,144 @@ BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
if (bytesPerRow < 0) if (bytesPerRow < 0)
bytesPerRow = bpr; bytesPerRow = bpr;
else if (bytesPerRow < bpr) else if (bytesPerRow < bpr)
// NOTE: How does R5 behave?
error = B_BAD_VALUE; error = B_BAD_VALUE;
} }
// allocate the bitmap buffer // allocate the bitmap buffer
if (error == B_OK) { if (error == B_OK) {
// NOTE: Maybe the code would look more robust if the
// "size" was not calculated here when we ask the server
// to allocate the bitmap. -Stephan
int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
#ifdef RUN_WITHOUT_APP_SERVER
fBasePtr = malloc(size);
if (fBasePtr) {
fSize = size;
fColorSpace = colorSpace;
fBounds = bounds;
fBytesPerRow = bytesPerRow;
fFlags = flags;
} else
error = B_NO_MEMORY;
#else
// Ask the server (via our owning application) to create a bitmap.
// Attach Data: if (flags & B_BITMAP_NO_SERVER_LINK) {
// 1) BRect bounds fBasePtr = malloc(size);
// 2) color_space space if (fBasePtr) {
// 3) int32 bitmap_flags fSize = size;
// 4) int32 bytes_per_row fColorSpace = colorSpace;
// 5) int32 screen_id::id fBounds = bounds;
link.StartMessage(AS_CREATE_BITMAP); fBytesPerRow = bytesPerRow;
link.Attach<BRect>(bounds); fFlags = flags;
link.Attach<color_space>(colorSpace); } else
link.Attach<int32>((int32)flags); error = B_NO_MEMORY;
link.Attach<int32>(bytesPerRow); } else {
link.Attach<int32>(screenID.id); // Ask the server (via our owning application) to create a bitmap.
BPrivate::BAppServerLink link;
// Reply Code: SERVER_TRUE
// Reply Data: // Attach Data:
// 1) int32 server token // 1) BRect bounds
// 2) area_id id of the area in which the bitmap data resides // 2) color_space space
// 3) int32 area pointer offset used to calculate fBasePtr // 3) int32 bitmap_flags
// 4) int32 bytes_per_row
// alternatively, if something went wrong // 5) int32 screen_id::id
// Reply Code: SERVER_FALSE link.StartMessage(AS_CREATE_BITMAP);
// Reply Data: link.Attach<BRect>(bounds);
// None link.Attach<color_space>(colorSpace);
int32 code = SERVER_FALSE; link.Attach<int32>((int32)flags);
error=link.FlushWithReply(&code); link.Attach<int32>(bytesPerRow);
link.Attach<int32>(screenID.id);
// We shouldn't ever have to execute this block, but just in case...
if(error!=B_OK)
fBasePtr=NULL;
if(code==SERVER_TRUE)
{
// Get token
area_id bmparea;
int32 areaoffset;
link.Read<int32>(&fServerToken); // Reply Code: SERVER_TRUE
link.Read<area_id>(&bmparea); // Reply Data:
link.Read<int32>(&areaoffset); // 1) int32 server token
// 2) area_id id of the area in which the bitmap data resides
// 3) int32 area pointer offset used to calculate fBasePtr
// Get the area in which the data resides // alternatively, if something went wrong
fArea=clone_area("shared bitmap area",(void**)&fBasePtr,B_ANY_ADDRESS, // Reply Code: SERVER_FALSE
B_READ_AREA | B_WRITE_AREA,bmparea); // Reply Data:
// None
int32 code = SERVER_FALSE;
error = link.FlushWithReply(&code);
// Jump to the location in the area if (error >= B_OK) {
fBasePtr=(int8*)fBasePtr + areaoffset; // *communication* with server successful
if (code == SERVER_TRUE) {
fSize = size; // server side success
fColorSpace = colorSpace; // Get token
fBounds = bounds; area_id bmparea;
fBytesPerRow = bytesPerRow; int32 areaoffset;
fFlags = flags;
link.Read<int32>(&fServerToken);
link.Read<area_id>(&bmparea);
link.Read<int32>(&areaoffset);
// Get the area in which the data resides
fArea = clone_area("shared bitmap area",
(void**)&fBasePtr,
B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA,
bmparea);
// Jump to the location in the area
fBasePtr = (int8*)fBasePtr + areaoffset;
fSize = size;
fColorSpace = colorSpace;
fBounds = bounds;
fBytesPerRow = bytesPerRow;
fFlags = flags;
} else {
// server side error, we assume:
error = B_NO_MEMORY;
}
}
// NOTE: not "else" to handle B_NO_MEMORY on server side!
if (error < B_OK) {
fBasePtr = NULL;
fServerToken = -1;
fArea = -1;
// NOTE: why not "0" in case of error?
fFlags = flags;
}
} }
else
{
fServerToken = -1;
fArea = -1;
fFlags = flags;
error = B_NO_MEMORY;
}
#endif // RUN_WITHOUT_APP_SERVER
fWindow = NULL; fWindow = NULL;
fToken = -1; fToken = -1;
fOrigArea = -1; fOrigArea = -1;
} }
// TODO: on success, handle clearing to white if the flags say so. Needs to be
// dependent on color space.
fInitError = error; fInitError = error;
} }
// CleanUp
/*! \brief Cleans up any memory allocated by the bitmap or
informs the server to do so.
*/
void
BBitmap::CleanUp()
{
if (fBasePtr) {
if (fFlags & B_BITMAP_NO_SERVER_LINK) {
free(fBasePtr);
} else {
BPrivate::BAppServerLink link;
// AS_DELETE_BITMAP:
// Attached Data:
// 1) int32 server token
// Reply Code: SERVER_TRUE if successful,
// SERVER_FALSE if the buffer was already deleted
// Reply Data: none
// status_t freestat;
int32 code = SERVER_FALSE;
link.StartMessage(AS_DELETE_BITMAP);
link.Attach<int32>(fServerToken);
link.FlushWithReply(&code);
if (code == SERVER_FALSE) {
// TODO: Find out if "SERVER_FALSE if the buffer
// was already deleted" is true. If not, maybe we
// need to take additional action.
}
fArea = -1;
fServerToken = -1;
}
fBasePtr = NULL;
}
}
// AssertPtr // AssertPtr
/*! \brief ??? /*! \brief ???
*/ */