Remove Windows-specific synchronous plugin drawing code. (bug 1218688 part 1, r=jimm)

This commit is contained in:
David Anderson 2015-10-28 10:50:36 -07:00
parent 2d03d7ff21
commit 15f76f10c1
9 changed files with 0 additions and 526 deletions

View File

@ -188,9 +188,6 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
mWsInfo.display = DefaultXDisplay();
#endif
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
#if defined(OS_WIN)
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
#endif // OS_WIN
#if defined(OS_WIN)
InitPopupMenuHook();
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
@ -821,21 +818,6 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
if (WM_NULL == evcopy.event)
return true;
// Painting for win32. SharedSurfacePaint handles everything.
if (mWindow.type == NPWindowTypeDrawable) {
if (evcopy.event == WM_PAINT) {
*handled = SharedSurfacePaint(evcopy);
return true;
}
else if (DoublePassRenderingEvent() == evcopy.event) {
// We'll render to mSharedSurfaceDib first, then render to a cached bitmap
// we store locally. The two passes are for alpha extraction, so the second
// pass must be to a flat white surface in order for things to work.
mAlphaExtract.doublePass = RENDER_BACK_ONE;
*handled = true;
return true;
}
}
*handled = WinlessHandleEvent(evcopy);
return true;
#endif
@ -1296,13 +1278,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
}
break;
case NPWindowTypeDrawable:
mWindow.type = aWindow.type;
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
SetupFlashMsgThrottle();
return SharedSurfaceSetWindow(aWindow);
break;
default:
NS_NOTREACHED("Bad plugin window type.");
return false;
@ -2024,187 +1999,6 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
return handled;
}
/* windowless drawing helpers */
bool
PluginInstanceChild::SharedSurfaceSetWindow(const NPRemoteWindow& aWindow)
{
// If the surfaceHandle is empty, parent is telling us we can reuse our cached
// memory surface and hdc. Otherwise, we need to reset, usually due to a
// expanding plugin port size.
if (!aWindow.surfaceHandle) {
if (!mSharedSurfaceDib.IsValid()) {
return false;
}
}
else {
// Attach to the new shared surface parent handed us.
if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
aWindow.width, aWindow.height, false)))
return false;
// Free any alpha extraction resources if needed. This will be reset
// the next time it's used.
AlphaExtractCacheRelease();
}
// NPRemoteWindow's origin is the origin of our shared dib.
mWindow.x = aWindow.x;
mWindow.y = aWindow.y;
mWindow.width = aWindow.width;
mWindow.height = aWindow.height;
mWindow.type = aWindow.type;
mWindow.window = reinterpret_cast<void*>(mSharedSurfaceDib.GetHDC());
::SetViewportOrgEx(mSharedSurfaceDib.GetHDC(),
-aWindow.x, -aWindow.y, nullptr);
if (mPluginIface->setwindow)
mPluginIface->setwindow(&mData, &mWindow);
return true;
}
void
PluginInstanceChild::SharedSurfaceRelease()
{
mSharedSurfaceDib.Close();
AlphaExtractCacheRelease();
}
/* double pass cache buffer - (rarely) used in cases where alpha extraction
* occurs for windowless plugins. */
bool
PluginInstanceChild::AlphaExtractCacheSetup()
{
AlphaExtractCacheRelease();
mAlphaExtract.hdc = ::CreateCompatibleDC(nullptr);
if (!mAlphaExtract.hdc)
return false;
BITMAPINFOHEADER bmih;
memset((void*)&bmih, 0, sizeof(BITMAPINFOHEADER));
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = mWindow.width;
bmih.biHeight = mWindow.height;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
void* ppvBits = nullptr;
mAlphaExtract.bmp = ::CreateDIBSection(mAlphaExtract.hdc,
(BITMAPINFO*)&bmih,
DIB_RGB_COLORS,
(void**)&ppvBits,
nullptr,
(unsigned long)sizeof(BITMAPINFOHEADER));
if (!mAlphaExtract.bmp)
return false;
DeleteObject(::SelectObject(mAlphaExtract.hdc, mAlphaExtract.bmp));
return true;
}
void
PluginInstanceChild::AlphaExtractCacheRelease()
{
if (mAlphaExtract.bmp)
::DeleteObject(mAlphaExtract.bmp);
if (mAlphaExtract.hdc)
::DeleteObject(mAlphaExtract.hdc);
mAlphaExtract.bmp = nullptr;
mAlphaExtract.hdc = nullptr;
}
void
PluginInstanceChild::UpdatePaintClipRect(RECT* aRect)
{
if (aRect) {
// Update the clip rect on our internal hdc
HRGN clip = ::CreateRectRgnIndirect(aRect);
::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
::DeleteObject(clip);
}
}
int16_t
PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
{
if (!mPluginIface->event)
return false;
RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
switch(mAlphaExtract.doublePass) {
case RENDER_NATIVE:
// pass the internal hdc to the plugin
UpdatePaintClipRect(pRect);
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
return mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
break;
case RENDER_BACK_ONE:
// Handle a double pass render used in alpha extraction for transparent
// plugins. (See nsPluginFrame and gfxWindowsNativeDrawing for details.)
// We render twice, once to the shared dib, and once to a cache which
// we copy back on a second paint. These paints can't be spread across
// multiple rpc messages as delays cause animation frame changes.
if (!mAlphaExtract.bmp && !AlphaExtractCacheSetup()) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
// See gfxWindowsNativeDrawing, color order doesn't have to match.
UpdatePaintClipRect(pRect);
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
// Copy to cache. We render to shared dib so we don't have to call
// setwindow between calls (flash issue).
::BitBlt(mAlphaExtract.hdc,
pRect->left,
pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top,
mSharedSurfaceDib.GetHDC(),
pRect->left,
pRect->top,
SRCCOPY);
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
mAlphaExtract.doublePass = RENDER_BACK_TWO;
return true;
break;
case RENDER_BACK_TWO:
// copy our cached surface back
UpdatePaintClipRect(pRect);
::BitBlt(mSharedSurfaceDib.GetHDC(),
pRect->left,
pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top,
mAlphaExtract.hdc,
pRect->left,
pRect->top,
SRCCOPY);
mAlphaExtract.doublePass = RENDER_NATIVE;
return true;
break;
}
return false;
}
/* flash msg throttling helpers */
// Flash has the unfortunate habit of flooding dispatch loops with custom
@ -4049,7 +3843,6 @@ PluginInstanceChild::Destroy()
mCachedElementActor = nullptr;
#if defined(OS_WIN)
SharedSurfaceRelease();
DestroyWinlessPopupSurrogate();
UnhookWinlessFlashThrottle();
DestroyPluginWindow();

View File

@ -427,29 +427,6 @@ private:
*/
nsAutoPtr< nsTHashtable<DeletingObjectEntry> > mDeletingHash;
#if defined(OS_WIN)
private:
// Shared dib rendering management for windowless plugins.
bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow);
int16_t SharedSurfacePaint(NPEvent& evcopy);
void SharedSurfaceRelease();
bool AlphaExtractCacheSetup();
void AlphaExtractCacheRelease();
void UpdatePaintClipRect(RECT* aRect);
private:
enum {
RENDER_NATIVE,
RENDER_BACK_ONE,
RENDER_BACK_TWO
};
gfx::SharedDIBWin mSharedSurfaceDib;
struct {
uint16_t doublePass;
HDC hdc;
HBITMAP bmp;
} mAlphaExtract;
#endif // defined(OS_WIN)
#if defined(MOZ_WIDGET_COCOA)
private:
#if defined(__i386__)

View File

@ -176,7 +176,6 @@ PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
if (why == AbnormalShutdown) {
// If the plugin process crashes, this is the only
// chance we get to destroy resources.
SharedSurfaceRelease();
UnsubclassPluginWindow();
}
#endif
@ -204,7 +203,6 @@ PluginInstanceParent::Destroy()
}
#if defined(OS_WIN)
SharedSurfaceRelease();
UnsubclassPluginWindow();
#endif
@ -949,11 +947,6 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
#if defined(OS_WIN)
// On windowless controls, reset the shared memory surface as needed.
if (mWindowType == NPWindowTypeDrawable) {
// SharedSurfaceSetWindow will take care of NPRemoteWindow.
if (!SharedSurfaceSetWindow(aWindow, window)) {
return NPERR_OUT_OF_MEMORY_ERROR;
}
MaybeCreateChildPopupSurrogate();
} else {
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
@ -1188,23 +1181,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
#if defined(OS_WIN)
if (mWindowType == NPWindowTypeDrawable) {
if (DoublePassRenderingEvent() == npevent->event) {
return CallPaint(npremoteevent, &handled) && handled;
}
switch (npevent->event) {
case WM_PAINT:
{
RECT rect;
SharedSurfaceBeforePaint(rect, npremoteevent);
if (!CallPaint(npremoteevent, &handled)) {
handled = false;
}
SharedSurfaceAfterPaint(npevent);
return handled;
}
break;
case WM_KILLFOCUS:
{
// When the user selects fullscreen mode in Flash video players,
@ -1936,108 +1913,6 @@ PluginInstanceParent::UnsubclassPluginWindow()
* painting: mPluginPort (nsIntRect, saved in SetWindow)
*/
void
PluginInstanceParent::SharedSurfaceRelease()
{
mSharedSurfaceDib.Close();
}
bool
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
NPRemoteWindow& aRemoteWindow)
{
aRemoteWindow.window = 0;
aRemoteWindow.x = aWindow->x;
aRemoteWindow.y = aWindow->y;
aRemoteWindow.width = aWindow->width;
aRemoteWindow.height = aWindow->height;
aRemoteWindow.type = aWindow->type;
nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
// save the the rect location within the browser window.
mPluginPort = newPort;
// move the port to our shared surface origin
newPort.MoveTo(0,0);
// check to see if we have the room in shared surface
if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
// ok to paint
aRemoteWindow.surfaceHandle = 0;
return true;
}
// allocate a new shared surface
SharedSurfaceRelease();
if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
newPort.width, newPort.height, false)))
return false;
// save the new shared surface size we just allocated
mSharedSize = newPort;
base::SharedMemoryHandle handle;
if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(OtherPid(), &handle))) {
return false;
}
aRemoteWindow.surfaceHandle = handle;
return true;
}
void
PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
NPRemoteEvent& npremoteevent)
{
RECT* dr = (RECT*)npremoteevent.event.lParam;
HDC parentHdc = (HDC)npremoteevent.event.wParam;
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
::BitBlt(mSharedSurfaceDib.GetHDC(),
dirtyRect.x,
dirtyRect.y,
dirtyRect.width,
dirtyRect.height,
parentHdc,
dr->left,
dr->top,
SRCCOPY);
// setup the translated dirty rect we'll send to the child
rect.left = dirtyRect.x;
rect.top = dirtyRect.y;
rect.right = dirtyRect.x + dirtyRect.width;
rect.bottom = dirtyRect.y + dirtyRect.height;
npremoteevent.event.wParam = WPARAM(0);
npremoteevent.event.lParam = LPARAM(&rect);
}
void
PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
{
RECT* dr = (RECT*)npevent->lParam;
HDC parentHdc = (HDC)npevent->wParam;
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
// src copy the shared dib into the parent surface we are handed.
::BitBlt(parentHdc,
dr->left,
dr->top,
dirtyRect.width,
dirtyRect.height,
mSharedSurfaceDib.GetHDC(),
dirtyRect.x,
dirtyRect.y,
SRCCOPY);
}
bool
PluginInstanceParent::MaybeCreateAndParentChildPluginWindow()
{

View File

@ -353,11 +353,6 @@ private:
#if defined(OS_WIN)
private:
// Used in rendering windowless plugins in other processes.
bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
void SharedSurfaceAfterPaint(NPEvent* npevent);
void SharedSurfaceRelease();
// Used in handling parent/child forwarding of events.
static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
@ -368,7 +363,6 @@ private:
void MaybeCreateChildPopupSurrogate();
private:
gfx::SharedDIBWin mSharedSurfaceDib;
nsIntRect mPluginPort;
nsIntRect mSharedSize;
HWND mPluginHWND;

View File

@ -54,9 +54,6 @@ NPRemoteWindow::NPRemoteWindow() :
, visualID(0)
, colormap(0)
#endif /* XP_UNIX */
#if defined(XP_WIN)
,surfaceHandle(0)
#endif
#if defined(XP_MACOSX)
,contentsScaleFactor(1.0)
#endif
@ -156,18 +153,5 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
VOID_TO_NPVARIANT(*v);
}
#ifdef XP_WIN
// The private event used for double-pass widgetless plugin rendering.
UINT DoublePassRenderingEvent()
{
static UINT gEventID = 0;
if (!gEventID)
gEventID = ::RegisterWindowMessage(L"MozDoublePassMsg");
return gEventID;
}
#endif
} // namespace plugins
} // namespace mozilla

View File

@ -93,9 +93,6 @@ struct NPRemoteWindow
VisualID visualID;
Colormap colormap;
#endif /* XP_UNIX */
#if defined(XP_WIN)
base::SharedMemoryHandle surfaceHandle;
#endif
#if defined(XP_MACOSX)
double contentsScaleFactor;
#endif
@ -254,11 +251,6 @@ struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
bool mDeleted;
};
#ifdef XP_WIN
// The private event used for double-pass widgetless plugin rendering.
UINT DoublePassRenderingEvent();
#endif
} /* namespace plugins */
} /* namespace mozilla */
@ -345,9 +337,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
aMsg->WriteULong(aParam.visualID);
aMsg->WriteULong(aParam.colormap);
#endif
#if defined(XP_WIN)
WriteParam(aMsg, aParam.surfaceHandle);
#endif
#if defined(XP_MACOSX)
aMsg->WriteDouble(aParam.contentsScaleFactor);
#endif
@ -377,12 +366,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
return false;
#endif
#if defined(XP_WIN)
base::SharedMemoryHandle surfaceHandle;
if (!ReadParam(aMsg, aIter, &surfaceHandle))
return false;
#endif
#if defined(XP_MACOSX)
double contentsScaleFactor;
if (!aMsg->ReadDouble(aIter, &contentsScaleFactor))
@ -400,9 +383,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
aResult->visualID = visualID;
aResult->colormap = colormap;
#endif
#if defined(XP_WIN)
aResult->surfaceHandle = surfaceHandle;
#endif
#if defined(XP_MACOSX)
aResult->contentsScaleFactor = contentsScaleFactor;
#endif

View File

@ -184,28 +184,6 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
}
}
bool
gfxWindowsNativeDrawing::IsDoublePass()
{
if (mContext->GetDrawTarget()->GetBackendType() != mozilla::gfx::BackendType::CAIRO ||
mContext->GetDrawTarget()->IsDualDrawTarget()) {
return true;
}
RefPtr<gfxASurface> surf = mContext->CurrentSurface(&mDeviceOffset.x, &mDeviceOffset.y);
if (!surf || surf->CairoStatus())
return false;
if (surf->GetType() != gfxSurfaceType::Win32 &&
surf->GetType() != gfxSurfaceType::Win32Printing) {
return true;
}
if ((surf->GetContentType() != gfxContentType::COLOR ||
(surf->GetContentType() == gfxContentType::COLOR_ALPHA &&
!(mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
return true;
return false;
}
bool
gfxWindowsNativeDrawing::ShouldRenderAgain()
{

View File

@ -79,9 +79,6 @@ public:
/* Returns true if the native drawing should be executed again */
bool ShouldRenderAgain();
/* Returns true if double pass alpha extraction is taking place. */
bool IsDoublePass();
/* Places the result to the context, if necessary */
void PaintToContext();

View File

@ -1666,110 +1666,6 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
}
}
#elif defined(XP_WIN)
RefPtr<nsNPAPIPluginInstance> inst;
GetPluginInstance(getter_AddRefs(inst));
if (inst) {
gfxRect frameGfxRect =
PresContext()->AppUnitsToGfxUnits(aPluginRect);
gfxRect dirtyGfxRect =
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
gfxContext *ctx = aRenderingContext.ThebesContext();
gfxMatrix currentMatrix = ctx->CurrentMatrix();
if (ctx->UserToDevicePixelSnapped(frameGfxRect, false)) {
dirtyGfxRect = ctx->UserToDevice(dirtyGfxRect);
ctx->SetMatrix(gfxMatrix());
}
dirtyGfxRect.RoundOut();
// Look if it's windowless
NPWindow *window;
mInstanceOwner->GetWindow(window);
if (window->type == NPWindowTypeDrawable) {
// the offset of the DC
nsPoint origin;
gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
if (nativeDraw.IsDoublePass()) {
// OOP plugin specific: let the shim know before we paint if we are doing a
// double pass render. If this plugin isn't oop, the register window message
// will be ignored.
NPEvent pluginEvent;
pluginEvent.event = plugins::DoublePassRenderingEvent();
pluginEvent.wParam = 0;
pluginEvent.lParam = 0;
if (pluginEvent.event)
inst->HandleEvent(&pluginEvent, nullptr);
}
do {
HDC hdc = nativeDraw.BeginNativeDrawing();
if (!hdc)
return;
RECT dest;
nativeDraw.TransformToNativeRect(frameGfxRect, dest);
RECT dirty;
nativeDraw.TransformToNativeRect(dirtyGfxRect, dirty);
window->window = hdc;
window->x = dest.left;
window->y = dest.top;
window->clipRect.left = 0;
window->clipRect.top = 0;
// if we're painting, we're visible.
window->clipRect.right = window->width;
window->clipRect.bottom = window->height;
// Windowless plugins on windows need a special event to update their location,
// see bug 135737.
//
// bug 271442: note, the rectangle we send is now purely the bounds of the plugin
// relative to the window it is contained in, which is useful for the plugin to
// correctly translate mouse coordinates.
//
// this does not mesh with the comments for bug 135737 which imply that the rectangle
// must be clipped in some way to prevent the plugin attempting to paint over areas
// it shouldn't.
//
// since the two uses of the rectangle are mutually exclusive in some cases, and
// since I don't see any incorrect painting (at least with Flash and ViewPoint -
// the originator of bug 135737), it seems that windowless plugins are not relying
// on information here for clipping their drawing, and we can safely use this message
// to tell the plugin exactly where it is in all cases.
nsIntPoint origin = GetWindowOriginInPixels(true);
nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
if (!mWindowlessRect.IsEqualEdges(winlessRect)) {
mWindowlessRect = winlessRect;
WINDOWPOS winpos;
memset(&winpos, 0, sizeof(winpos));
winpos.x = mWindowlessRect.x;
winpos.y = mWindowlessRect.y;
winpos.cx = mWindowlessRect.width;
winpos.cy = mWindowlessRect.height;
// finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event
NPEvent pluginEvent;
pluginEvent.event = WM_WINDOWPOSCHANGED;
pluginEvent.wParam = 0;
pluginEvent.lParam = (LPARAM)&winpos;
inst->HandleEvent(&pluginEvent, nullptr);
}
inst->SetWindow(window);
mInstanceOwner->Paint(dirty, hdc);
nativeDraw.EndNativeDrawing();
} while (nativeDraw.ShouldRenderAgain());
nativeDraw.PaintToContext();
}
ctx->SetMatrix(currentMatrix);
}
#endif
}