Bug 57409 - [WinCairo] Implement Missing drawWindowsBitmap
Summary: [WinCairo] Implement Missing drawWindowsBitmap
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows 7
: P2 Normal
Assignee: Brent Fulgham
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-29 17:41 PDT by Brent Fulgham
Modified: 2011-03-31 20:11 PDT (History)
4 users (show)

See Also:


Attachments
Implementation of missing drawWindowsBitmap for WinCairo port. (2.24 KB, patch)
2011-03-29 17:45 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (8.92 KB, patch)
2011-03-30 14:31 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (19.22 KB, patch)
2011-03-30 17:47 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (19.14 KB, patch)
2011-03-31 11:02 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (17.64 KB, patch)
2011-03-31 11:06 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (18.35 KB, patch)
2011-03-31 12:09 PDT, Brent Fulgham
no flags Details | Formatted Diff | Diff
Patch (18.20 KB, patch)
2011-03-31 15:14 PDT, Brent Fulgham
aroben: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Brent Fulgham 2011-03-29 17:41:56 PDT
When playing with the ENABLE(VIDEO) options, I realized there was a missing GraphicsContext method needed for the WinCairo port.
Comment 1 Brent Fulgham 2011-03-29 17:45:26 PDT
Created attachment 87444 [details]
Implementation of missing drawWindowsBitmap for WinCairo port.
Comment 2 Martin Robinson 2011-03-30 13:10:49 PDT
Comment on attachment 87444 [details]
Implementation of missing drawWindowsBitmap for WinCairo port.

View in context: https://bugs.webkit.org/attachment.cgi?id=87444&action=review

It seems like this code and the code in GraphicsContext::releaseWindowsContext are almost identical. Is it possible to refactor it out into a helper function?

> Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:160
> +                                            CAIRO_FORMAT_ARGB32,
> +                                            image->size().width(),
> +                                            image->size().height(),
> +                                            image->bytesPerRow());
> +

Please line these up with the opening (.

> Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:166
> +    cairo_scale(m_data->cr, 1.0, -1.0);

This should just be:

cairo_scale(m_data->cr, 1, -1);
Comment 3 Brent Fulgham 2011-03-30 14:31:47 PDT
Created attachment 87617 [details]
Patch
Comment 4 Brent Fulgham 2011-03-30 17:47:41 PDT
Created attachment 87646 [details]
Patch
Comment 5 Adam Roben (:aroben) 2011-03-30 18:24:48 PDT
Comment on attachment 87646 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=87646&action=review

> Source/WebCore/platform/graphics/GraphicsContext.h:460
> +            IntSize size() const { return m_bitmapBits.size(); }

Should be a const IntSize&.

> Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp:91
> +GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, GraphicsContext::WindowsBitmap::FromActiveBitmapType)
> +    : m_hdc(hdc)
> +{
> +    m_bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
> +    m_bitmapBits.initializeFromHBitmap(m_bitmap);
> +}

This will still result in the HDC and HBITMAP being destroyed when the WindowsBitmap is destroyed. That seems undesirable and wrong.

> Source/WebCore/platform/win/WindowsDIB.cpp:31
> +WindowsDIB::WindowsDIB(const HBITMAP& bitmap)

No need for the const&. HBITMAP is just a pointer.

Seems like this class should be in platform/graphics/win.

> Source/WebCore/platform/win/WindowsDIB.cpp:46
> +void WindowsDIB::initializeFromHBitmap(const HBITMAP& bitmap)
> +{
> +    BITMAP bmpInfo;
> +    GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
> +
> +    m_bitmapBuffer = reinterpret_cast<UInt8*>(bmpInfo.bmBits);
> +    m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
> +    m_size = IntSize(bmpInfo.bmWidth, bmpInfo.bmHeight);
> +    m_bytesPerRow = bmpInfo.bmWidthBytes;
> +    m_bitsPerPixel = bmpInfo.bmBitsPixel;
> +}

Why not just do this in the constructor?

No need for the const&. HBITMAP is just a pointer.

> Source/WebCore/platform/win/WindowsDIB.h:54
> +        IntSize size() const { return m_size; }

Should be a const IntSize&.
Comment 6 Brent Fulgham 2011-03-30 19:37:24 PDT
(In reply to comment #5)
> > Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp:91
> > +GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, GraphicsContext::WindowsBitmap::FromActiveBitmapType)
> > +    : m_hdc(hdc)
> > +{
> > +    m_bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
> > +    m_bitmapBits.initializeFromHBitmap(m_bitmap);
> > +}
> 
> This will still result in the HDC and HBITMAP being destroyed when the WindowsBitmap is destroyed. That seems undesirable and wrong.

I thought that was the desired function of the existing WindowsBitmap inner class, since that was how it was originally designed.

If the change you suggest is made, we'll have to manually destroy the HDC and HBITMAP context when the WindowsBitmap goes out of scope to retain the same behavior as the current WebKit implementation.  I assumed this object was created to help avoid this manual cleanup.
Comment 7 Adam Roben (:aroben) 2011-03-30 19:43:12 PDT
(In reply to comment #6)
> (In reply to comment #5)
> > > Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp:91
> > > +GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, GraphicsContext::WindowsBitmap::FromActiveBitmapType)
> > > +    : m_hdc(hdc)
> > > +{
> > > +    m_bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
> > > +    m_bitmapBits.initializeFromHBitmap(m_bitmap);
> > > +}
> > 
> > This will still result in the HDC and HBITMAP being destroyed when the WindowsBitmap is destroyed. That seems undesirable and wrong.
> 
> I thought that was the desired function of the existing WindowsBitmap inner class, since that was how it was originally designed.
> 
> If the change you suggest is made, we'll have to manually destroy the HDC and HBITMAP context when the WindowsBitmap goes out of scope to retain the same behavior as the current WebKit implementation.  I assumed this object was created to help avoid this manual cleanup.

I see. I'd suggest making the current code use OwnPtr to hold the HDC and HBITMAP, and then use your new WindowsDIB class instead of WindowsBitmap. You can leave WindowsBitmap untouched in that case.
Comment 8 Brent Fulgham 2011-03-30 19:45:15 PDT
(In reply to comment #7)
> I see. I'd suggest making the current code use OwnPtr to hold the HDC and HBITMAP, and then use your new WindowsDIB class instead of WindowsBitmap. You can leave WindowsBitmap untouched in that case.

Okay -- I'll give that a shot tomorrow!

Thanks for all the helpful reviews.  :-)
Comment 9 Brent Fulgham 2011-03-31 10:18:51 PDT
(In reply to comment #5)
> > +void WindowsDIB::initializeFromHBitmap(const HBITMAP& bitmap)
> > +{
> > +    BITMAP bmpInfo;
> > +    GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
> > +
> > +    m_bitmapBuffer = reinterpret_cast<UInt8*>(bmpInfo.bmBits);
> > +    m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
> > +    m_size = IntSize(bmpInfo.bmWidth, bmpInfo.bmHeight);
> > +    m_bytesPerRow = bmpInfo.bmWidthBytes;
> > +    m_bitsPerPixel = bmpInfo.bmBitsPixel;
> > +}
> 
> Why not just do this in the constructor?

I don't have an HBITMAP during construction of the overall WindowsBitmap, so I default construct an empty object, then populate it using the "initializeFromHBitmap" later on.  If that wasn't the case, this could all be moved into the constructor.
Comment 10 Brent Fulgham 2011-03-31 11:02:52 PDT
Created attachment 87767 [details]
Patch
Comment 11 Brent Fulgham 2011-03-31 11:06:15 PDT
Created attachment 87769 [details]
Patch
Comment 12 Build Bot 2011-03-31 11:54:24 PDT
Attachment 87769 [details] did not build on win:
Build output: http://queues.webkit.org/results/8311403
Comment 13 Brent Fulgham 2011-03-31 12:09:14 PDT
Created attachment 87775 [details]
Patch
Comment 14 Adam Roben (:aroben) 2011-03-31 14:03:00 PDT
Comment on attachment 87775 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=87775&action=review

It seems buggy that releaseWindowsContext doesn't select the HDC's original bitmap back into it before calling ::DeleteDC. That's not a new problem, though.

This is looking good. Let's do one more pass to nail down the last few things.

> Source/WebCore/platform/graphics/GraphicsContext.h:447
> +

I don't think this extra line is needed.

> Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp:101
> +    OwnPtr<HBITMAP> bitmap(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)));

The more modern way of writing this is to use assignment and adoptPtr.

> Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:99
> +static void drawBitmapToContext(GraphicsContextPlatformPrivate* context, const WindowsDIB& windowsDIB, double tx, double ty)

tx/ty would be better as an IntSize or FloatSize. (I think only ints are passed in?)

> Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:137
> +    OwnPtr<HBITMAP> bitmap(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)));

Same comment here about adoptPtr.

> Source/WebCore/platform/graphics/win/WindowsDIB.h:39
> +class WindowsDIB {

Since this class doesn't hold onto the DIB itself, maybe a name like DIBData or DIBPixelData would be better.

> Source/WebCore/platform/graphics/win/WindowsDIB.h:48
> +        WindowsDIB(HBITMAP);

This should be marked explicit.

> Source/WebCore/platform/graphics/win/WindowsDIB.h:50
> +        void initializeFromHBitmap(const HBITMAP&);

No need for the const&. I think "FromHBitmap" could be removed, too.
Comment 15 Brent Fulgham 2011-03-31 14:40:47 PDT
(In reply to comment #14)
> (From update of attachment 87775 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=87775&action=review
> 
> It seems buggy that releaseWindowsContext doesn't select the HDC's original bitmap back into it before calling ::DeleteDC. That's not a new problem, though.

Wouldn't we have to cache the original bitmap someplace?  Or is there a stock bitmap we can reselect?  Either way, I'd prefer to do that as a separate issue to avoid breaking something unexpected.

> > Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:99
> > +static void drawBitmapToContext(GraphicsContextPlatformPrivate* context, const WindowsDIB& windowsDIB, double tx, double ty)
> 
> tx/ty would be better as an IntSize or FloatSize. (I think only ints are passed in?)

These are x,y coordinates to translate to.  I could use an IntPoint, which might be clearer.

Cairo expects to deal with doubles for these two values, so it seemed easier just to take the arguments as doubles, even though the original values are integers as you point out.

I'll switch to an IntPoint for the argument.
Comment 16 Brent Fulgham 2011-03-31 15:14:14 PDT
Created attachment 87795 [details]
Patch
Comment 17 Adam Roben (:aroben) 2011-03-31 15:40:27 PDT
(In reply to comment #15)
> (In reply to comment #14)
> > (From update of attachment 87775 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=87775&action=review
> > 
> > It seems buggy that releaseWindowsContext doesn't select the HDC's original bitmap back into it before calling ::DeleteDC. That's not a new problem, though.
> 
> Wouldn't we have to cache the original bitmap someplace?  Or is there a stock bitmap we can reselect?  Either way, I'd prefer to do that as a separate issue to avoid breaking something unexpected.

Yes, we'd have to cache the original bitmap. And yes, this should not be done as part of this patch.

> > > Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp:99
> > > +static void drawBitmapToContext(GraphicsContextPlatformPrivate* context, const WindowsDIB& windowsDIB, double tx, double ty)
> > 
> > tx/ty would be better as an IntSize or FloatSize. (I think only ints are passed in?)
> 
> These are x,y coordinates to translate to.  I could use an IntPoint, which might be clearer.

Usually translation is talked about as being a translation by a certain distance, not a translation to a certain point (though the two are of course equivalent). So I'd still argue that IntSize is better than IntPoint.
Comment 18 Adam Roben (:aroben) 2011-03-31 15:42:36 PDT
Comment on attachment 87795 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=87795&action=review

> Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp:71
> +    UInt8* storage = 0;

You could make this a void* to avoid the cast.
Comment 19 Brent Fulgham 2011-03-31 15:47:25 PDT
(In reply to comment #17)
> > These are x,y coordinates to translate to.  I could use an IntPoint, which might be clearer.
> 
> Usually translation is talked about as being a translation by a certain distance, not a translation to a certain point (though the two are of course equivalent). So I'd still argue that IntSize is better than IntPoint.

Ok.  IntSize it is!
Comment 20 Brent Fulgham 2011-03-31 20:11:01 PDT
Landed in http://trac.webkit.org/changeset/82640