Bug 528551- Faster plugin drawing in Fennec. r=jst/karlt.

This commit is contained in:
Doug Turner 2009-11-20 08:26:10 -08:00
Родитель eaf40161ba
Коммит 364165c463
5 изменённых файлов: 372 добавлений и 188 удалений

Просмотреть файл

@ -39,11 +39,13 @@
interface nsIObjectFrame;
interface nsIPluginInstance;
interface nsIDOMElement;
interface nsIDOMClientRect;
/**
* This interface represents a content node that loads objects.
*/
[scriptable, uuid(90ab443e-3e99-405e-88c9-9c42adaa3217)]
[scriptable, uuid(8afe3b08-293c-48bd-a997-321745478611)]
interface nsIObjectLoadingContent : nsISupports
{
const unsigned long TYPE_LOADING = 0;
@ -105,4 +107,12 @@ interface nsIObjectLoadingContent : nsISupports
* because nsIObjectFrame is unscriptable.
*/
[noscript] void hasNewFrame(in nsIObjectFrame aFrame);
/**
* Tells the object to paint directly in this location ignoring any
* positioning information that may have been provided otherwise
*/
void setAbsoluteScreenPosition(in nsIDOMElement element,
in nsIDOMClientRect position,
in nsIDOMClientRect clip);
};

Просмотреть файл

@ -890,7 +890,6 @@ nsObjectLoadingContent::GetInterface(const nsIID & aIID, void **aResult)
NS_ADDREF(sink);
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -1872,3 +1871,17 @@ nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
return ePluginBlocklisted;
return ePluginUnsupported;
}
NS_IMETHODIMP
nsObjectLoadingContent::SetAbsoluteScreenPosition(nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip)
{
nsIObjectFrame* frame = GetExistingFrame(eFlushLayout);
if (!frame)
return NS_ERROR_NOT_AVAILABLE;
return frame->SetAbsoluteScreenPosition(element, position, clip);
}

Просмотреть файл

@ -94,6 +94,14 @@ public:
* Get the native widget for the plugin, if any.
*/
virtual nsIWidget* GetWidget() = 0;
/**
* Tells the object to paint directly in this location ignoring any
* positioning information that may have been provided otherwise.
*/
virtual nsresult SetAbsoluteScreenPosition(class nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip) = 0;
};
#endif /* nsIObjectFrame_h___ */

Просмотреть файл

@ -108,6 +108,7 @@
#include "nsIImageLoadingContent.h"
#include "nsIObjectLoadingContent.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMElement.h"
#include "nsContentUtils.h"
#include "nsDisplayList.h"
#include "nsAttrName.h"
@ -124,6 +125,7 @@
#include "nsIXPConnect.h"
#include "nsIXPCScriptable.h"
#include "nsIClassInfo.h"
#include "nsIDOMClientRect.h"
#include "nsObjectFrame.h"
#include "nsIObjectFrame.h"
@ -172,6 +174,16 @@ enum { XKeyPress = KeyPress };
#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2)
#define MOZ_COMPOSITED_PLUGINS 1
#include "gfxXlibSurface.h"
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#ifdef MOZ_WIDGET_GTK2
@ -331,11 +343,6 @@ public:
void SetPluginHost(nsIPluginHost* aHost);
#ifdef MOZ_PLATFORM_HILDON
/* the flash plugin(s) need to have thier visiblity poked */
PRBool UpdateVisibility(PRBool aForce = PR_FALSE);
#endif
nsEventStatus ProcessEvent(const nsGUIEvent & anEvent);
#ifdef XP_MACOSX
@ -405,6 +412,12 @@ public:
return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0;
}
#ifdef MOZ_PLATFORM_HILDON
nsresult SetAbsoluteScreenPosition(nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip);
#endif
private:
void FixUpURLS(const nsString &name, nsAString &value);
@ -498,15 +511,34 @@ private:
#ifdef MOZ_PLATFORM_HILDON
// On hildon, we attempt to use NPImageExpose which allows us faster
// painting. We hold a memory buffer to avoid reallocations on
// every plugin invalidate.
unsigned char* mImageExposeBuffer;
gfxIntSize mImageExposeBufferSize;
// painting.
// used to keep track of how big our buffer is.
nsIntSize mPluginSize;
// the scale between the actual instance plugin window and what
// we want to scale it to.
float mPluginScale;
// the element that was passed into SetAbsoluteScreenPosition().
// This will be the element we use to determine which Window we draw into.
nsCOMPtr<nsIDOMElement> mBlitParentElement;
// The absolute position on the screen to draw to.
nsIntRect mAbsolutePosition;
// The clip region that we should draw into.
nsIntRect mAbsolutePositionClip;
Window mBlitWindow;
XImage *mSharedXImage;
XShmSegmentInfo mSharedSegmentInfo;
PRBool SetupXShm();
void ReleaseXShm();
nsresult NativeImageDraw();
PRBool UpdateVisibility();
nsresult NativeImageDraw(gfxContext *aContext,
NPWindow* mWindow,
const nsIntSize& mPluginSize,
const nsIntRect& mDirtyRect);
#endif
};
@ -931,10 +963,6 @@ nsObjectFrame::FixupWindow(const nsSize& aSize)
NS_ENSURE_TRUE(window, /**/);
#ifdef MOZ_PLATFORM_HILDON
mInstanceOwner->UpdateVisibility(PR_TRUE);
#endif
#ifdef XP_MACOSX
mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable);
#endif
@ -978,11 +1006,6 @@ nsObjectFrame::CallSetWindow()
return;
nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
#ifdef MOZ_PLATFORM_HILDON
mInstanceOwner->UpdateVisibility(PR_TRUE);
#endif
#ifdef XP_MACOSX
mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable);
#endif
@ -1190,6 +1213,19 @@ nsObjectFrame::ComputeWidgetGeometry(const nsRegion& aRegion,
}
}
nsresult
nsObjectFrame::SetAbsoluteScreenPosition(nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip)
{
#ifdef MOZ_PLATFORM_HILDON
NS_ASSERTION(mInstanceOwner, "failed to get mInstanceOwner");
return mInstanceOwner->SetAbsoluteScreenPosition(element, position, clip);
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
void
nsObjectFrame::DidSetWidgetGeometry()
{
@ -2363,15 +2399,10 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
#endif
#ifdef MOZ_PLATFORM_HILDON
mImageExposeBuffer = nsnull;
mImageExposeBufferSize = gfxIntSize(0,0);
#endif
#ifdef XP_MACOSX
#ifndef NP_NO_QUICKDRAW
mEventModel = NPEventModelCarbon;
#else
mEventModel = NPEventModelCocoa;
#endif
mPluginSize = nsIntSize(0,0);
mPluginScale = 1.0;
mSharedXImage = nsnull;
mSharedSegmentInfo.shmaddr = nsnull;
#endif
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("nsPluginInstanceOwner %p created\n", this));
@ -2428,11 +2459,8 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
}
#ifdef MOZ_PLATFORM_HILDON
if (mImageExposeBuffer)
free(mImageExposeBuffer);
mImageExposeBuffer = nsnull;
ReleaseXShm();
#endif
}
/*
@ -2649,6 +2677,11 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
{
#ifdef MOZ_PLATFORM_HILDON
if (mObjectFrame && mBlitWindow && NS_SUCCEEDED(NativeImageDraw()))
return NS_OK;
#endif
if (!mObjectFrame || !invalidRect || !mWidgetVisible)
return NS_ERROR_FAILURE;
@ -3485,10 +3518,6 @@ nsPluginInstanceOwner::GetEventloopNestingLevel()
nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#ifdef MOZ_PLATFORM_HILDON
CancelTimer();
#endif
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
if (GetEventModel() != NPEventModelCarbon)
return NS_OK;
@ -4735,7 +4764,18 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
if (!mInstance || !mObjectFrame)
return;
// Align to device pixels where sensible
#ifdef MOZ_PLATFORM_HILDON
PRBool simpleImageRender = PR_FALSE;
mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool,
&simpleImageRender);
if (simpleImageRender) {
gfxMatrix matrix = aContext->CurrentMatrix();
if (!matrix.HasNonAxisAlignedTransform() &&
NS_SUCCEEDED(NativeImageDraw()))
return;
}
#endif
// to provide crisper and faster drawing.
gfxRect pluginRect = aFrameRect;
if (aContext->UserToDevicePixelSnapped(pluginRect)) {
@ -4788,15 +4828,6 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
gfxContextAutoSaveRestore autoSR(aContext);
aContext->Translate(pluginRect.pos);
#ifdef MOZ_PLATFORM_HILDON
PRBool simpleImageRender = PR_FALSE;
mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool, (void *)&simpleImageRender);
if (simpleImageRender && NS_SUCCEEDED(NativeImageDraw(aContext, window, pluginSize, pluginDirtyRect)))
return;
#endif
Renderer renderer(window, mInstance, pluginSize, pluginDirtyRect);
renderer.Draw(aContext, window->width, window->height,
rendererFlags, nsnull);
@ -4821,6 +4852,103 @@ DepthOfVisual(const Screen* screen, const Visual* visual)
#ifdef MOZ_PLATFORM_HILDON
static GdkWindow* GetClosestWindow(nsIDOMElement *element)
{
nsCOMPtr<nsIDOMDocument> domDocument;
element->GetOwnerDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDocument);
if (!doc)
return nsnull;
nsIPresShell *presShell = doc->GetPrimaryShell();
if (!presShell)
return nsnull;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
nsIFrame* frame = presShell->GetPrimaryFrameFor(content);
if (!frame)
return nsnull;
nsIWidget* win = frame->GetWindow();
if (!win)
return nsnull;
GdkWindow* w = static_cast<GdkWindow*>(win->GetNativeData(NS_NATIVE_WINDOW));
return w;
}
void
nsPluginInstanceOwner::ReleaseXShm()
{
if (mSharedSegmentInfo.shmaddr) {
XShmDetach(gdk_x11_get_default_xdisplay(), &mSharedSegmentInfo);
shmdt(mSharedSegmentInfo.shmaddr);
mSharedSegmentInfo.shmaddr = nsnull;
}
if (mSharedXImage) {
XDestroyImage(mSharedXImage);
mSharedXImage = nsnull;
}
}
PRBool
nsPluginInstanceOwner::SetupXShm()
{
mBlitWindow = GDK_WINDOW_XWINDOW(GetClosestWindow(mBlitParentElement));
if (!mBlitWindow)
return PR_FALSE;
ReleaseXShm();
// we use 16 as the default depth because that is the value of the
// screen, but not the default X default depth.
XVisualInfo vinfo;
int foundVisual = XMatchVisualInfo(gdk_x11_get_default_xdisplay(),
gdk_x11_get_default_screen(),
16,
TrueColor,
&vinfo);
if (!foundVisual)
return PR_FALSE;
memset(&mSharedSegmentInfo, 0, sizeof(XShmSegmentInfo));
mSharedXImage = XShmCreateImage(gdk_x11_get_default_xdisplay(),
vinfo.visual,
16,
ZPixmap,
0,
&mSharedSegmentInfo,
mPluginSize.width,
mPluginSize.height);
if (!mSharedXImage)
return PR_FALSE;
mSharedSegmentInfo.shmid = shmget(IPC_PRIVATE,
mSharedXImage->bytes_per_line * mSharedXImage->height,
IPC_CREAT | 0777);
mSharedXImage->data = static_cast<char*>(shmat(mSharedSegmentInfo.shmid, 0, 0));
mSharedSegmentInfo.shmaddr = mSharedXImage->data;
mSharedSegmentInfo.readOnly = False;
Status s = XShmAttach(gdk_x11_get_default_xdisplay(), &mSharedSegmentInfo);
XSync(gdk_x11_get_default_xdisplay(), False);
shmctl(mSharedSegmentInfo.shmid, IPC_RMID, 0);
if (!s) {
// attach failed, call shmdt and null shmaddr before calling
// ReleaseXShm().
shmdt(mSharedSegmentInfo.shmaddr);
mSharedSegmentInfo.shmaddr = nsnull;
ReleaseXShm();
return PR_FALSE;
}
return PR_TRUE;
}
// NativeImageDraw
//
// This method supports the NPImageExpose API which is specific to the
@ -4840,65 +4968,53 @@ DepthOfVisual(const Screen* screen, const Visual* visual)
// Hopefully this API can die off in favor of a more robust plugin API.
nsresult
nsPluginInstanceOwner::NativeImageDraw(gfxContext *aContext,
NPWindow* mWindow,
const nsIntSize& mPluginSize,
const nsIntRect& mDirtyRect)
nsPluginInstanceOwner::NativeImageDraw()
{
PRBool doupdatewindow = PR_FALSE;
// if we haven't been positioned yet, ignore
if (!mBlitParentElement)
return NS_OK;
if (mWindow->x || mWindow->y) {
mWindow->x = 0;
mWindow->y = 0;
doupdatewindow = PR_TRUE;
}
// if the clip rect is zero, we have nothing to do.
if (mAbsolutePositionClip.width == 0 || mAbsolutePositionClip.height == 0)
return NS_OK;
if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
mWindow->width = mPluginSize.width;
mWindow->height = mPluginSize.height;
doupdatewindow = PR_TRUE;
}
// if we haven't been setup before, or if the size of the plugin increased.
if (!mSharedXImage ||
mPluginSize.width != mAbsolutePosition.width ||
mPluginSize.height != mAbsolutePosition.height) {
// The clip rect is relative to drawable top-left.
nsIntRect clipRect;
clipRect.x = 0;
clipRect.y = 0;
clipRect.width = mWindow->width;
clipRect.height = mWindow->height;
mPluginSize = nsIntSize(mAbsolutePosition.width, mAbsolutePosition.height);
if (NS_FAILED(SetupXShm()))
return NS_ERROR_FAILURE;
}
NPWindow* window;
GetWindow(window);
NS_ASSERTION(window, "Window can not be null");
// setup window such that it knows about the size and clip. This
// is to work around a flash clipping bug when using the Image
// Expose API.
NPRect newClipRect;
newClipRect.left = clipRect.x;
newClipRect.top = clipRect.y;
newClipRect.right = clipRect.XMost();
newClipRect.bottom = clipRect.YMost();
if (mWindow->clipRect.left != newClipRect.left ||
mWindow->clipRect.top != newClipRect.top ||
mWindow->clipRect.right != newClipRect.right ||
mWindow->clipRect.bottom != newClipRect.bottom) {
mWindow->clipRect = newClipRect;
doupdatewindow = PR_TRUE;
}
newClipRect.left = 0;
newClipRect.top = 0;
newClipRect.right = window->width;
newClipRect.bottom = window->height;
window->clipRect = newClipRect;
window->x = 0;
window->y = 0;
NPSetWindowCallbackStruct* ws_info =
static_cast<NPSetWindowCallbackStruct*>(mWindow->ws_info);
static_cast<NPSetWindowCallbackStruct*>(window->ws_info);
ws_info->visual = 0;
ws_info->colormap = 0;
if (ws_info->depth != 24) {
ws_info->depth = 24;
doupdatewindow = PR_TRUE;
}
ws_info->depth = 16;
mInstance->SetWindow(window);
if (doupdatewindow)
mInstance->SetWindow(mWindow);
nsIntRect dirtyRect = mDirtyRect;
// Intersect the dirty rect with the clip rect to ensure that it lies within
// the drawable.
if (!dirtyRect.IntersectRect(mDirtyRect, clipRect))
return NS_ERROR_FAILURE;
XEvent pluginEvent;
NPEvent pluginEvent;
NPImageExpose imageExpose;
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
@ -4908,71 +5024,82 @@ nsPluginInstanceOwner::NativeImageDraw(gfxContext *aContext,
// Store imageExpose structure pointer as drawable member
exposeEvent.drawable = (Drawable)&imageExpose;
exposeEvent.x = mDirtyRect.x;
exposeEvent.y = mDirtyRect.y;
exposeEvent.width = mDirtyRect.width;
exposeEvent.height = mDirtyRect.height;
exposeEvent.count = 0;
// information not set:
exposeEvent.serial = 0;
exposeEvent.send_event = False;
exposeEvent.major_code = 0;
exposeEvent.minor_code = 0;
// defaults for NPImageExpose
imageExpose.depth = 24;
imageExpose.translateX = 1;
imageExpose.translateY = 1;
imageExpose.scaleX = 1;
imageExpose.scaleY = 1;
exposeEvent.x = 0;
exposeEvent.y = 0;
exposeEvent.width = window->width;
exposeEvent.height = window->height;
// only have the plugin draw what is dirty
imageExpose.x = mDirtyRect.x;
imageExpose.y = mDirtyRect.y;
imageExpose.width = mDirtyRect.width;
imageExpose.height = mDirtyRect.height;
imageExpose.x = 0;
imageExpose.y = 0;
imageExpose.width = window->width;
imageExpose.height = window->height;
// reallocate buffer if there is a size change or if we haven't allocated one yet. We probably can do this
// somewhere else.
if (!mImageExposeBuffer ||
(mImageExposeBufferSize.width * mImageExposeBufferSize.height < mWindow->width * mWindow->height)) {
if (mImageExposeBuffer)
free(mImageExposeBuffer);
imageExpose.depth = 16;
mImageExposeBuffer = (unsigned char*) malloc (mWindow->width * mWindow->height * 4);
mImageExposeBufferSize = gfxIntSize(mWindow->width, mWindow->height);
}
imageExpose.translateX = 0;
imageExpose.translateY = 0;
NS_ENSURE_TRUE(mImageExposeBuffer, NS_ERROR_OUT_OF_MEMORY);
imageExpose.scaleX = mPluginScale;
imageExpose.scaleY = mPluginScale;
// Because we are reusing mImageExposeBuffer, there might be old bytes. The API NPImageExpose
// expects that the buffer be zero'ed out.
memset(mImageExposeBuffer, 0, mImageExposeBufferSize.height * mImageExposeBufferSize.width * 4);
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(mImageExposeBuffer,
mImageExposeBufferSize,
mImageExposeBufferSize.width * 4,
gfxASurface::ImageFormatRGB24);
NS_ENSURE_TRUE(surf, NS_ERROR_OUT_OF_MEMORY);
// Setup temporary context scaled size
imageExpose.stride = surf->Stride();
imageExpose.data = reinterpret_cast<char*>(surf->Data());
imageExpose.dataSize.width = surf->Width();
imageExpose.dataSize.height = surf->Height();
imageExpose.stride = mPluginSize.width * 2;
imageExpose.data = mSharedXImage->data;
imageExpose.dataSize.width = mPluginSize.width;
imageExpose.dataSize.height = mPluginSize.height;
PRBool eventHandled = PR_FALSE;
// Get Image surface from original context
// Draw plugin content to temp surface
mInstance->HandleEvent(&pluginEvent, &eventHandled);
if (eventHandled) {
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
aContext->NewPath();
aContext->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWindow->width, mWindow->height), pat);
aContext->Fill();
if (!eventHandled) {
// XXX we should set a flag that the plugin didn't handle this event,
// and we should deallocate the SHM surface and just skip trying to
// draw this way
return NS_ERROR_FAILURE;
}
// Setup the clip rectangle
XRectangle rect;
rect.x = mAbsolutePositionClip.x;
rect.y = mAbsolutePositionClip.y;
rect.width = mAbsolutePositionClip.width;
rect.height = mAbsolutePositionClip.height;
GC gc = XCreateGC(gdk_x11_get_default_xdisplay(),
mBlitWindow,
0,
0);
if (!gc)
return NS_ERROR_FAILURE;
XSetClipRectangles(gdk_x11_get_default_xdisplay(),
gc,
mAbsolutePosition.x,
mAbsolutePosition.y,
&rect, 1,
Unsorted);
XShmPutImage(gdk_x11_get_default_xdisplay(),
mBlitWindow,
gc,
mSharedXImage,
0,
0,
mAbsolutePosition.x,
mAbsolutePosition.y,
mPluginSize.width,
mPluginSize.height,
PR_FALSE);
XSetClipRectangles(gdk_x11_get_default_xdisplay(), gc, 0, 0, nsnull, 0, Unsorted);
XFreeGC(gdk_x11_get_default_xdisplay(), gc);
XFlush(gdk_x11_get_default_xdisplay());
return NS_OK;
}
#endif
@ -5149,11 +5276,6 @@ nsPluginInstanceOwner::Renderer::NativeDraw(QWidget * drawable,
NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
{
#ifdef MOZ_PLATFORM_HILDON
if (mInstance)
UpdateVisibility();
#endif
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
if (GetEventModel() != NPEventModelCarbon)
return NS_OK;
@ -5204,20 +5326,6 @@ void nsPluginInstanceOwner::StartTimer(unsigned int aDelay)
mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_REPEATING_SLACK);
}
#endif
#ifdef MOZ_PLATFORM_HILDON
if (!mTimerCanceled)
return;
// start a periodic timer to provide null events to the plugin instance.
if (!mPluginTimer)
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mPluginTimer) {
mTimerCanceled = PR_FALSE;
mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_ONE_SHOT);
}
#endif
}
void nsPluginInstanceOwner::CancelTimer()
@ -5423,27 +5531,20 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
}
#ifdef MOZ_PLATFORM_HILDON
PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aForce)
PRBool nsPluginInstanceOwner::UpdateVisibility()
{
if (!mPluginWindow || !mInstance || !mObjectFrame)
return PR_FALSE;
NS_ASSERTION(mInstance, "mInstance should never be null");
PRBool handled;
NPEvent pluginEvent;
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
visibilityEvent.type = VisibilityNotify;
visibilityEvent.display = 0;
visibilityEvent.state = VisibilityUnobscured;
mInstance->HandleEvent(&pluginEvent, &handled);
// first, check our view for CSS visibility style
PRBool isVisible =
mObjectFrame->GetView()->GetVisibility() == nsViewVisibility_kShow;
if (aForce || mWidgetVisible != isVisible) {
PRBool handled;
NPEvent pluginEvent;
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
visibilityEvent.type = VisibilityNotify;
visibilityEvent.display = 0;
visibilityEvent.state = isVisible ? VisibilityUnobscured : VisibilityFullyObscured;
mInstance->HandleEvent(&pluginEvent, &handled);
mWidgetVisible = isVisible;
return PR_TRUE;
}
return PR_FALSE;
mWidgetVisible = PR_TRUE;
return PR_TRUE;
}
#endif
@ -5584,3 +5685,50 @@ void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value)
value = newURL;
}
}
#ifdef MOZ_PLATFORM_HILDON
nsresult
nsPluginInstanceOwner::SetAbsoluteScreenPosition(nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip)
{
if ((mBlitParentElement && (mBlitParentElement != element)) ||
!position || !clip)
return NS_ERROR_FAILURE;
// convert to a int rect.
float left, top, width, height;
position->GetLeft(&left);
position->GetTop(&top);
position->GetWidth(&width);
position->GetHeight(&height);
NPWindow *window;
GetWindow(window);
NS_ASSERTION(window, "Must have a window here");
mPluginScale = width / window->width;
// The flash plugin on Maemo n900 requires the width/height to be
// even.
mAbsolutePosition = nsIntRect(NSToIntFloor(left),
NSToIntFloor(top),
NSToIntCeil(width) / 2 * 2,
NSToIntCeil(height) / 2 * 2);
clip->GetLeft(&left);
clip->GetTop(&top);
clip->GetWidth(&width);
clip->GetHeight(&height);
mAbsolutePositionClip = nsIntRect(NSToIntFloor(left),
NSToIntFloor(top),
NSToIntCeil(width),
NSToIntCeil(height));
mBlitParentElement = element;
// The hildon plugin needs to have it visibility poked
UpdateVisibility();
return NS_OK;
}
#endif

Просмотреть файл

@ -58,6 +58,7 @@ class nsIPluginHost;
class nsIPluginInstance;
class nsPresContext;
class nsDisplayPlugin;
class nsIDOMElement;
#define nsObjectFrameSuper nsFrame
@ -220,6 +221,10 @@ protected:
nsIWidget* GetWidget() { return mWidget; }
nsresult SetAbsoluteScreenPosition(nsIDOMElement* element,
nsIDOMClientRect* position,
nsIDOMClientRect* clip);
friend class nsPluginInstanceOwner;
friend class nsDisplayPlugin;