Closed Bug 83631 Opened 24 years ago Closed 18 years ago

Need ability to create drawing surfaces with given pixel format

Categories

(Core Graveyard :: GFX, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 231620
Future

People

(Reporter: alex, Assigned: dcone)

References

Details

For the SVG we need a drawing surface with 24bpp since the rendering backend (libart) can't deal with other color depths. Unfortunately nsIRenderingContext::CreateDrawingSurface() can only create surfaces that match the color depth of the rendering context. I suggest adding a flag 'NS_CREATEDRAWINGSURFACE_24BIT' that can be passed to CreateDrawingSurface() to create a 24bpp surface (see patches below). At least for Windows, 24bpp surfaces are compatible with any rendering context, so they can be selected as offscreen surfaces even if the rendering context has a different pixel format. I don't know whether that is the case for other platforms. If there are platforms on which offscreen surfaces need to have the exact color format of the rendering context, the flag could just be ignored. Here are the proposed patches for Windows: Index: nsIDrawingSurface.h =================================================================== RCS file: /cvsroot/mozilla/gfx/public/nsIDrawingSurface.h,v retrieving revision 1.4 diff -u -r1.4 nsIDrawingSurface.h --- nsIDrawingSurface.h 2000/09/13 07:02:15 1.4 +++ nsIDrawingSurface.h 2001/06/01 07:58:11 @@ -145,6 +145,11 @@ //tiling, grouting etc. #define NS_CREATEDRAWINGSURFACE_SHORTLIVED 0x0002 +//if this flag is set, the color format of the created surface will be +//24bits RGB, independent of the color format of the device. Might not +//be supported on all devices. +#define NS_CREATEDRAWINGSURFACE_24BIT 0x0004 + //when locking a drawing surface, use these flags to //control how the data in the surface should be accessed #define NS_LOCK_SURFACE_READ_ONLY 0x0001 Index: nsDrawingSurfaceWin.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/windows/nsDrawingSurfaceWin.cpp,v retrieving revision 3.7 diff -u -r3.7 nsDrawingSurfaceWin.cpp --- nsDrawingSurfaceWin.cpp 2001/05/11 13:54:42 3.7 +++ nsDrawingSurfaceWin.cpp 2001/06/01 08:00:58 @@ -387,7 +387,10 @@ BITMAPINFO *binfo; int depth; - depth = ::GetDeviceCaps(aDC, BITSPIXEL); + if (aFlags & NS_CREATEDRAWINGSURFACE_24BIT) + depth = 24; + else + depth = ::GetDeviceCaps(aDC, BITSPIXEL); binfo = CreateBitmapInfo(aWidth, aHeight, depth);
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla1.0
Blocks: 80142
The following patch adds the necessary support to Mac - actually very easy becuase nsDrawingSurfaceMac already takes a 'depth' argument to ::Init(). Index: mozilla/gfx/src/mac/nsRenderingContextMac.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/mac/nsRenderingContextMac.cpp,v retrieving revision 1.124 diff -u -2 -r1.124 nsRenderingContextMac.cpp --- mozilla/gfx/src/mac/nsRenderingContextMac.cpp 2001/07/16 02:38:50 1.124 +++ mozilla/gfx/src/mac/nsRenderingContextMac.cpp 2001/08/01 11:08:19 @@ -494,4 +494,8 @@ mContext->GetDepth(depth); + if (aSurfFlags & NS_CREATEDRAWINGSURFACE_24BIT) + depth = 24; + // get rect
Ah, but how do we do this on unix, easily? (Can we? Can we do this on os2, beos, etc?) I'm still not convinced that this is the best solution - we're going to need to manipulate intermediate offscreen buffers anyway (filtering, group opacity, etc). Why can't we solve the original problem by telling libart that we're using 24 bit color, and then downsampling as needed just before we draw to the screen? Thats certainly better than going 16<->24 all the time. That aside, syd - do you know if there an easy way for an equivalent patch for unix?
OS: Windows 2000 → All
Hardware: PC → All
> Ah, but how do we do this on unix, easily? (Can we? Can we do this on os2, > beos, etc?) On Unix this will probably never work, unless the XServer happens to have a 24bit visual. We could fake it by copying the gdk (server-side) pixmap into a 24bit (client-side) buffer in nsGDKDrawingSurface::Lock() and using gdk_rgb to write the buffer to the pixmap in Unlock(). That would be stupid and slow though. > Why can't we solve the original problem by telling libart that > we're using 24 bit color, and then downsampling as needed just before > we draw to the screen? The old way of rendering the svg (i.e. going through nsIImage) is _exactely_ what you are suggesting plus it is cross-platform. The nice thing about drawing to surfaces is that we can select the same surface into the rendering context and use the rendering context functions to draw to it. In this way, we can interdisperse svg and <foreignObject>s such as html that are drawn using rendering context functions. This is something that is not feasible on Unix, unless we a) write a rendering context that can draw to 24bit buffers (easy) or b) have some X server extensions. I still think on platforms that support it, it is a good idea to be able to get a surface with some canonical pixel format.
Reassigning to dcone
Assignee: kmcclusk → dcone
Status: ASSIGNED → NEW
Target Milestone: mozilla1.0 → mozilla1.0.1
retargeting
Target Milestone: mozilla1.0.1 → Future
Obsoleted by Cairo.
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → DUPLICATE
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.