зеркало из https://github.com/mozilla/pjs.git
Bug 528551- Faster plugin drawing in Fennec. r=jst/karlt.
This commit is contained in:
Родитель
eaf40161ba
Коммит
364165c463
|
@ -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 we haven't been setup before, or if the size of the plugin increased.
|
||||
if (!mSharedXImage ||
|
||||
mPluginSize.width != mAbsolutePosition.width ||
|
||||
mPluginSize.height != mAbsolutePosition.height) {
|
||||
|
||||
mPluginSize = nsIntSize(mAbsolutePosition.width, mAbsolutePosition.height);
|
||||
|
||||
if (NS_FAILED(SetupXShm()))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
|
||||
mWindow->width = mPluginSize.width;
|
||||
mWindow->height = mPluginSize.height;
|
||||
doupdatewindow = PR_TRUE;
|
||||
}
|
||||
NPWindow* window;
|
||||
GetWindow(window);
|
||||
NS_ASSERTION(window, "Window can not be null");
|
||||
|
||||
// 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;
|
||||
// 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");
|
||||
|
||||
// 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;
|
||||
visibilityEvent.state = VisibilityUnobscured;
|
||||
mInstance->HandleEvent(&pluginEvent, &handled);
|
||||
mWidgetVisible = isVisible;
|
||||
|
||||
mWidgetVisible = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
#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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче