mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
bug 532344 - only issue one NS_PAINT event for each WM_PAINT on WinMo r=dougt
This commit is contained in:
parent
e4668b2b4d
commit
d3bc320ce8
@ -341,7 +341,6 @@ protected:
|
||||
void OnWindowPosChanged(WINDOWPOS *wp, PRBool& aResult);
|
||||
#if defined(CAIRO_HAS_DDRAW_SURFACE)
|
||||
PRBool OnPaintImageDDraw16();
|
||||
HRESULT PaintRectImageDDraw16(RECT aRect, nsPaintEvent* aEvent);
|
||||
#endif // defined(CAIRO_HAS_DDRAW_SURFACE)
|
||||
PRBool OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
PRBool& result, PRBool& getWheelInfo,
|
||||
|
@ -878,147 +878,31 @@ HBITMAP nsWindowGfx::DataToBitmap(PRUint8* aImageData,
|
||||
|
||||
// Windows Mobile Special image/direct draw painting fun
|
||||
#if defined(CAIRO_HAS_DDRAW_SURFACE)
|
||||
HRESULT nsWindow::PaintRectImageDDraw16(RECT rcPaint, nsPaintEvent* event){
|
||||
HRESULT hr;
|
||||
PRBool nsWindow::OnPaintImageDDraw16()
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
PAINTSTRUCT ps;
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
gfxIntSize surfaceSize;
|
||||
nsRefPtr<gfxImageSurface> targetSurfaceImage;
|
||||
nsRefPtr<gfxContext> thebesContext;
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
nsEventStatus eventStatus = nsEventStatus_eIgnore;
|
||||
RECT renderArea;
|
||||
|
||||
surfaceSize = gfxIntSize(rcPaint.right - rcPaint.left,
|
||||
rcPaint.bottom - rcPaint.top);
|
||||
|
||||
if (!EnsureSharedSurfaceSize(surfaceSize)) {
|
||||
NS_ERROR("Couldn't allocate shared surface!");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(),
|
||||
surfaceSize,
|
||||
surfaceSize.width * 4,
|
||||
gfxASurface::ImageFormatRGB24);
|
||||
|
||||
if (!targetSurfaceImage || targetSurfaceImage->CairoStatus()) {
|
||||
NS_ERROR("Invalid targetSurfaceImage!");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
targetSurfaceImage->SetDeviceOffset(gfxPoint(-rcPaint.left, -rcPaint.top));
|
||||
|
||||
thebesContext = new gfxContext(targetSurfaceImage);
|
||||
thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
|
||||
thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
|
||||
|
||||
nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CreateRenderingContextInstance failed");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
rv = rc->Init(mContext, thebesContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("RC::Init failed");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
event->renderingContext = rc;
|
||||
nsresult result = DispatchWindowEvent(event, eventStatus);
|
||||
event->renderingContext = nsnull;
|
||||
|
||||
if (!result) {
|
||||
printf("result is null from dispatch\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
hr = glpDDSecondary->Lock(0, &gDDSDSecondary, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD, 0); /* should we wait here? */
|
||||
if (FAILED(hr)) {
|
||||
#ifdef DEBUG
|
||||
DDError("Failed to lock renderer", hr);
|
||||
#endif
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Convert RGB24 -> RGB565
|
||||
pixman_image_t *srcPixmanImage = pixman_image_create_bits(PIXMAN_x8r8g8b8,
|
||||
surfaceSize.width,
|
||||
surfaceSize.height,
|
||||
(uint32_t*) sSharedSurfaceData.get(),
|
||||
surfaceSize.width * 4);
|
||||
|
||||
pixman_image_t *dstPixmanImage = pixman_image_create_bits(PIXMAN_r5g6b5,
|
||||
gDDSDSecondary.dwWidth,
|
||||
gDDSDSecondary.dwHeight,
|
||||
(uint32_t*) gDDSDSecondary.lpSurface,
|
||||
gDDSDSecondary.dwWidth * 2);
|
||||
|
||||
pixman_image_composite(PIXMAN_OP_SRC,
|
||||
srcPixmanImage,
|
||||
NULL,
|
||||
dstPixmanImage,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
surfaceSize.width,
|
||||
surfaceSize.height);
|
||||
|
||||
pixman_image_unref(dstPixmanImage);
|
||||
pixman_image_unref(srcPixmanImage);
|
||||
|
||||
hr = glpDDSecondary->Unlock(0);
|
||||
if (FAILED(hr)) {
|
||||
#ifdef DEBUG
|
||||
DDError("Failed to unlock renderer", hr);
|
||||
#endif
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = glpDDClipper->SetHWnd(0, mWnd);
|
||||
if (FAILED(hr)) {
|
||||
#ifdef DEBUG
|
||||
DDError("SetHWnd", hr);
|
||||
#endif
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// translate the paint region to screen coordinates
|
||||
renderArea = rcPaint;
|
||||
MapWindowPoints(mWnd, 0, (LPPOINT)&renderArea, 2);
|
||||
|
||||
// set the rect to be 0,0 based
|
||||
rcPaint.right = surfaceSize.width;
|
||||
rcPaint.bottom = surfaceSize.height;
|
||||
rcPaint.left = rcPaint.top = 0;
|
||||
|
||||
return glpDDPrimary->Blt(&renderArea,
|
||||
glpDDSecondary,
|
||||
&rcPaint,
|
||||
DDBLT_WAITNOTBUSY, /* should we really wait here? */
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
PRBool nsWindow::OnPaintImageDDraw16()
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
PAINTSTRUCT ps;
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
mPainting = PR_TRUE;
|
||||
PRInt32 brx, bry, brw, brh;
|
||||
gfxIntSize newSize;
|
||||
newSize.height = GetSystemMetrics(SM_CYSCREEN);
|
||||
newSize.width = GetSystemMetrics(SM_CXSCREEN);
|
||||
mPainting = PR_TRUE;
|
||||
|
||||
HDC hDC = ::BeginPaint(mWnd, &ps);
|
||||
mPaintDC = hDC;
|
||||
nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(PR_FALSE, ps, hDC);
|
||||
|
||||
if (!paintRgnWin || paintRgnWin->IsEmpty() || !mEventCallback) {
|
||||
printf("nothing to paint\n");
|
||||
result = PR_TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
InitEvent(event);
|
||||
|
||||
event.region = paintRgnWin;
|
||||
@ -1058,22 +942,108 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
paintRgnWin->GetBoundingBox(&brx, &bry, &brw, &brh);
|
||||
surfaceSize = gfxIntSize(brw, brh);
|
||||
|
||||
if (!EnsureSharedSurfaceSize(surfaceSize))
|
||||
goto cleanup;
|
||||
|
||||
targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(),
|
||||
surfaceSize,
|
||||
surfaceSize.width * 4,
|
||||
gfxASurface::ImageFormatRGB24);
|
||||
|
||||
if (!targetSurfaceImage || targetSurfaceImage->CairoStatus())
|
||||
goto cleanup;
|
||||
|
||||
targetSurfaceImage->SetDeviceOffset(gfxPoint(-brx, -bry));
|
||||
|
||||
thebesContext = new gfxContext(targetSurfaceImage);
|
||||
thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
|
||||
thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
|
||||
|
||||
nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
|
||||
rv = rc->Init(mContext, thebesContext);
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
|
||||
event.renderingContext = rc;
|
||||
PRBool res = DispatchWindowEvent(&event, eventStatus);
|
||||
event.renderingContext = nsnull;
|
||||
|
||||
if (!res && eventStatus == nsEventStatus_eConsumeNoDefault)
|
||||
goto cleanup;
|
||||
|
||||
nsRegionRectSet *rects = nsnull;
|
||||
RECT r;
|
||||
paintRgnWin->GetRects(&rects);
|
||||
|
||||
HRESULT hr = glpDDSecondary->Lock(0, &gDDSDSecondary, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD, 0);
|
||||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
||||
pixman_image_t *srcPixmanImage =
|
||||
pixman_image_create_bits(PIXMAN_x8r8g8b8, surfaceSize.width,
|
||||
surfaceSize.height,
|
||||
(uint32_t*) sSharedSurfaceData.get(),
|
||||
surfaceSize.width * 4);
|
||||
|
||||
pixman_image_t *dstPixmanImage =
|
||||
pixman_image_create_bits(PIXMAN_r5g6b5, gDDSDSecondary.dwWidth,
|
||||
gDDSDSecondary.dwHeight,
|
||||
(uint32_t*) gDDSDSecondary.lpSurface,
|
||||
gDDSDSecondary.dwWidth * 2);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < rects->mNumRects; i++) {
|
||||
pixman_image_composite(PIXMAN_OP_SRC, srcPixmanImage, NULL, dstPixmanImage,
|
||||
rects->mRects[i].x - brx, rects->mRects[i].y - bry,
|
||||
0, 0,
|
||||
rects->mRects[i].x, rects->mRects[i].y,
|
||||
rects->mRects[i].width, rects->mRects[i].height);
|
||||
|
||||
}
|
||||
|
||||
pixman_image_unref(dstPixmanImage);
|
||||
pixman_image_unref(srcPixmanImage);
|
||||
|
||||
hr = glpDDSecondary->Unlock(0);
|
||||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
||||
hr = glpDDClipper->SetHWnd(0, mWnd);
|
||||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
||||
for (unsigned int i = 0; i < rects->mNumRects; i++) {
|
||||
r.left = rects->mRects[i].x;
|
||||
r.top = rects->mRects[i].y;
|
||||
r.right = rects->mRects[i].width + rects->mRects[i].x;
|
||||
r.bottom = rects->mRects[i].height + rects->mRects[i].y;
|
||||
PaintRectImageDDraw16(r, &event);
|
||||
RECT renderRect = r;
|
||||
SetLastError(0); // See http://msdn.microsoft.com/en-us/library/dd145046%28VS.85%29.aspx
|
||||
if (MapWindowPoints(mWnd, 0, (LPPOINT)&renderRect, 2) || 0 == (hr = GetLastError()))
|
||||
hr = glpDDPrimary->Blt(&renderRect, glpDDSecondary, &r, 0, NULL);
|
||||
if (FAILED(hr))
|
||||
// add this rect back to the invalidated region so we'll attempt paint it next time around
|
||||
mInvalidatedRegion->Union(rects->mRects[i].x, rects->mRects[i].y,
|
||||
rects->mRects[i].width, rects->mRects[i].height);
|
||||
}
|
||||
result = PR_TRUE;
|
||||
|
||||
cleanup:
|
||||
|
||||
// re-invalidate the region if we failed.
|
||||
if (!result)
|
||||
mInvalidatedRegion->Union(*paintRgnWin.get());
|
||||
|
||||
::EndPaint(mWnd, &ps);
|
||||
mPaintDC = nsnull;
|
||||
mPainting = PR_FALSE;
|
||||
return result;
|
||||
|
||||
}
|
||||
#endif // defined(CAIRO_HAS_DDRAW_SURFACE)
|
||||
|
Loading…
Reference in New Issue
Block a user