зеркало из https://github.com/mozilla/gecko-dev.git
Bug 521257 - Support NPImageExpose on Maemo/Hildon only. r=roc
This commit is contained in:
Родитель
b5f3112586
Коммит
cc4f335fc9
|
@ -139,6 +139,8 @@
|
||||||
#include "gfxWindowsSurface.h"
|
#include "gfxWindowsSurface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "gfxImageSurface.h"
|
||||||
|
|
||||||
// accessibility support
|
// accessibility support
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
#include "nsIAccessibilityService.h"
|
#include "nsIAccessibilityService.h"
|
||||||
|
@ -169,7 +171,6 @@ enum { XKeyPress = KeyPress };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_PLATFORM_HILDON
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
#define MOZ_POST_VISIBILITY_EVENTS 1
|
|
||||||
#define MOZ_COMPOSITED_PLUGINS 1
|
#define MOZ_COMPOSITED_PLUGINS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -543,7 +544,19 @@ private:
|
||||||
const nsIntRect& mDirtyRect;
|
const nsIntRect& mDirtyRect;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
#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;
|
||||||
|
|
||||||
|
nsresult NativeImageDraw(gfxContext *aContext,
|
||||||
|
NPWindow* mWindow,
|
||||||
|
const nsIntSize& mPluginSize,
|
||||||
|
const nsIntRect& mDirtyRect);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mac specific code to fix up port position and clip
|
// Mac specific code to fix up port position and clip
|
||||||
|
@ -2383,6 +2396,10 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||||
mLastPoint = nsIntPoint(0,0);
|
mLastPoint = nsIntPoint(0,0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
mImageExposeBuffer = nsnull;
|
||||||
|
mImageExposeBufferSize = gfxIntSize(0,0);
|
||||||
|
#endif
|
||||||
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
|
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
|
||||||
("nsPluginInstanceOwner %p created\n", this));
|
("nsPluginInstanceOwner %p created\n", this));
|
||||||
}
|
}
|
||||||
|
@ -2436,6 +2453,13 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
||||||
if (mInstance) {
|
if (mInstance) {
|
||||||
mInstance->InvalidateOwner();
|
mInstance->InvalidateOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
if (mImageExposeBuffer)
|
||||||
|
free(mImageExposeBuffer);
|
||||||
|
mImageExposeBuffer = nsnull;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3228,7 +3252,7 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
|
||||||
mNumCachedAttrs++;
|
mNumCachedAttrs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "plugins.force.wmode" preference is forcing wmode type for plguins
|
// "plugins.force.wmode" preference is forcing wmode type for plugins
|
||||||
// possible values - "opaque", "transparent", "windowed"
|
// possible values - "opaque", "transparent", "windowed"
|
||||||
nsAdoptingCString wmodeType = nsContentUtils::GetCharPref("plugins.force.wmode");
|
nsAdoptingCString wmodeType = nsContentUtils::GetCharPref("plugins.force.wmode");
|
||||||
if (!wmodeType.IsEmpty())
|
if (!wmodeType.IsEmpty())
|
||||||
|
@ -4762,7 +4786,6 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||||
NPWindow* window;
|
NPWindow* window;
|
||||||
GetWindow(window);
|
GetWindow(window);
|
||||||
|
|
||||||
Renderer renderer(window, mInstance, pluginSize, pluginDirtyRect);
|
|
||||||
PRUint32 rendererFlags =
|
PRUint32 rendererFlags =
|
||||||
Renderer::DRAW_SUPPORTS_OFFSET |
|
Renderer::DRAW_SUPPORTS_OFFSET |
|
||||||
Renderer::DRAW_SUPPORTS_CLIP_RECT |
|
Renderer::DRAW_SUPPORTS_CLIP_RECT |
|
||||||
|
@ -4778,6 +4801,16 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||||
gfxContextAutoSaveRestore autoSR(aContext);
|
gfxContextAutoSaveRestore autoSR(aContext);
|
||||||
aContext->Translate(pluginRect.pos);
|
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,
|
renderer.Draw(aContext, window->width, window->height,
|
||||||
rendererFlags, nsnull);
|
rendererFlags, nsnull);
|
||||||
}
|
}
|
||||||
|
@ -4799,6 +4832,164 @@ DepthOfVisual(const Screen* screen, const Visual* visual)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
|
||||||
|
// NativeImageDraw
|
||||||
|
//
|
||||||
|
// This method supports the NPImageExpose API which is specific to the
|
||||||
|
// HILDON platform. Basically what it allows us to do is to pass a
|
||||||
|
// memory buffer into a plugin (namely flash), and have flase draw
|
||||||
|
// directly into the buffer.
|
||||||
|
//
|
||||||
|
// It may be faster if the rest of the system used offscreen image
|
||||||
|
// surfaces, but right now offscreen surfaces are using X
|
||||||
|
// surfaces. And because of this, we need to create a new image
|
||||||
|
// surface and copy that to the passed gfx context.
|
||||||
|
//
|
||||||
|
// This is not ideal and it should not be faster than what a
|
||||||
|
// windowless plugin can do. However, in A/B testing of flash on the
|
||||||
|
// N900, this approach is considerably faster.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
PRBool doupdatewindow = PR_FALSE;
|
||||||
|
|
||||||
|
if (mWindow->x || mWindow->y) {
|
||||||
|
mWindow->x = 0;
|
||||||
|
mWindow->y = 0;
|
||||||
|
doupdatewindow = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
|
||||||
|
mWindow->width = mPluginSize.width;
|
||||||
|
mWindow->height = mPluginSize.height;
|
||||||
|
doupdatewindow = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPSetWindowCallbackStruct* ws_info =
|
||||||
|
static_cast<NPSetWindowCallbackStruct*>(mWindow->ws_info);
|
||||||
|
ws_info->visual = 0;
|
||||||
|
ws_info->colormap = 0;
|
||||||
|
if (ws_info->depth != 24) {
|
||||||
|
ws_info->depth = 24;
|
||||||
|
doupdatewindow = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
NPImageExpose imageExpose;
|
||||||
|
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
|
||||||
|
|
||||||
|
// set the drawing info
|
||||||
|
exposeEvent.type = GraphicsExpose;
|
||||||
|
exposeEvent.display = 0;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// only have the plugin draw what is dirty
|
||||||
|
imageExpose.x = mDirtyRect.x;
|
||||||
|
imageExpose.y = mDirtyRect.y;
|
||||||
|
imageExpose.width = mDirtyRect.width;
|
||||||
|
imageExpose.height = mDirtyRect.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);
|
||||||
|
|
||||||
|
mImageExposeBuffer = (unsigned char*) malloc (mWindow->width * mWindow->height * 4);
|
||||||
|
mImageExposeBufferSize = gfxIntSize(mWindow->width, mWindow->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_TRUE(mImageExposeBuffer, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_GTK2)
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
nsresult
|
nsresult
|
||||||
nsPluginInstanceOwner::Renderer::NativeDraw(GdkDrawable * drawable,
|
nsPluginInstanceOwner::Renderer::NativeDraw(GdkDrawable * drawable,
|
||||||
|
|
|
@ -337,6 +337,10 @@ typedef enum {
|
||||||
/* Used for negotiating event models */
|
/* Used for negotiating event models */
|
||||||
, NPPVpluginEventModel = 1001
|
, NPPVpluginEventModel = 1001
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
, NPPVpluginWindowlessLocalBool = 2002
|
||||||
|
#endif
|
||||||
} NPPVariable;
|
} NPPVariable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -379,6 +383,9 @@ typedef enum {
|
||||||
#endif
|
#endif
|
||||||
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
|
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
, NPNVSupportsWindowlessLocal = 2002
|
||||||
|
#endif
|
||||||
} NPNVariable;
|
} NPNVariable;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -419,6 +426,21 @@ typedef struct _NPWindow
|
||||||
NPWindowType type; /* Is this a window or a drawable? */
|
NPWindowType type; /* Is this a window or a drawable? */
|
||||||
} NPWindow;
|
} NPWindow;
|
||||||
|
|
||||||
|
typedef struct _NPImageExpose
|
||||||
|
{
|
||||||
|
char* data; /* image pointer */
|
||||||
|
int32_t stride; /* Stride of data image pointer */
|
||||||
|
int32_t depth; /* Depth of image pointer */
|
||||||
|
int32_t x; /* Expose x */
|
||||||
|
int32_t y; /* Expose y */
|
||||||
|
uint32_t width; /* Expose width */
|
||||||
|
uint32_t height; /* Expose height */
|
||||||
|
NPSize dataSize; /* Data buffer size */
|
||||||
|
float translateX; /* translate X matrix value */
|
||||||
|
float translateY; /* translate Y matrix value */
|
||||||
|
float scaleX; /* scale X matrix value */
|
||||||
|
float scaleY; /* scale Y matrix value */
|
||||||
|
} NPImageExpose;
|
||||||
|
|
||||||
typedef struct _NPFullPrint
|
typedef struct _NPFullPrint
|
||||||
{
|
{
|
||||||
|
|
|
@ -1980,6 +1980,13 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
case NPNVSupportsWindowlessLocal: {
|
||||||
|
*(NPBool*)result = PR_TRUE;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
case NPNVpluginDrawingModel: {
|
case NPNVpluginDrawingModel: {
|
||||||
if (npp) {
|
if (npp) {
|
||||||
|
@ -2103,7 +2110,12 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||||
return inst->SetWindowless(bWindowless);
|
return inst->SetWindowless(bWindowless);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
case NPPVpluginWindowlessLocalBool: {
|
||||||
|
NPBool bWindowlessLocal = (result != nsnull);
|
||||||
|
return inst->SetWindowlessLocal(bWindowlessLocal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
case NPPVpluginTransparentBool: {
|
case NPPVpluginTransparentBool: {
|
||||||
NPBool bTransparent = (result != nsnull);
|
NPBool bTransparent = (result != nsnull);
|
||||||
return inst->SetTransparent(bTransparent);
|
return inst->SetTransparent(bTransparent);
|
||||||
|
|
|
@ -881,6 +881,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
mWindowless(PR_FALSE),
|
mWindowless(PR_FALSE),
|
||||||
|
mWindowlessLocal(PR_FALSE),
|
||||||
mTransparent(PR_FALSE),
|
mTransparent(PR_FALSE),
|
||||||
mStarted(PR_FALSE),
|
mStarted(PR_FALSE),
|
||||||
mCached(PR_FALSE),
|
mCached(PR_FALSE),
|
||||||
|
@ -1382,6 +1383,14 @@ NS_IMETHODIMP nsNPAPIPluginInstance::HandleEvent(void* event, PRBool* handled)
|
||||||
|
|
||||||
NS_IMETHODIMP nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable, void* value)
|
NS_IMETHODIMP nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable, void* value)
|
||||||
{
|
{
|
||||||
|
#ifdef MOZ_PLATFORM_HILDON
|
||||||
|
// The maemo flash plugin does not remember this. It sets the
|
||||||
|
// value, but doesn't support the get value.
|
||||||
|
if (variable == NPPVpluginWindowlessLocalBool) {
|
||||||
|
*(NPBool*)value = mWindowlessLocal;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
nsresult res = NS_OK;
|
nsresult res = NS_OK;
|
||||||
if (mCallbacks->getvalue && mStarted) {
|
if (mCallbacks->getvalue && mStarted) {
|
||||||
PluginDestructionGuard guard(this);
|
PluginDestructionGuard guard(this);
|
||||||
|
@ -1421,6 +1430,12 @@ NPError nsNPAPIPluginInstance::SetWindowless(PRBool aWindowless)
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NPError nsNPAPIPluginInstance::SetWindowlessLocal(PRBool aWindowlessLocal)
|
||||||
|
{
|
||||||
|
mWindowlessLocal = aWindowlessLocal;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
NPError nsNPAPIPluginInstance::SetTransparent(PRBool aTransparent)
|
NPError nsNPAPIPluginInstance::SetTransparent(PRBool aTransparent)
|
||||||
{
|
{
|
||||||
mTransparent = aTransparent;
|
mTransparent = aTransparent;
|
||||||
|
|
|
@ -86,6 +86,8 @@ public:
|
||||||
|
|
||||||
NPError SetWindowless(PRBool aWindowless);
|
NPError SetWindowless(PRBool aWindowless);
|
||||||
|
|
||||||
|
NPError SetWindowlessLocal(PRBool aWindowlessLocal);
|
||||||
|
|
||||||
NPError SetTransparent(PRBool aTransparent);
|
NPError SetTransparent(PRBool aTransparent);
|
||||||
|
|
||||||
NPError SetWantsAllNetworkStreams(PRBool aWantsAllNetworkStreams);
|
NPError SetWantsAllNetworkStreams(PRBool aWantsAllNetworkStreams);
|
||||||
|
@ -149,6 +151,7 @@ protected:
|
||||||
// these are used to store the windowless properties
|
// these are used to store the windowless properties
|
||||||
// which the browser will later query
|
// which the browser will later query
|
||||||
PRPackedBool mWindowless;
|
PRPackedBool mWindowless;
|
||||||
|
PRPackedBool mWindowlessLocal;
|
||||||
PRPackedBool mTransparent;
|
PRPackedBool mTransparent;
|
||||||
PRPackedBool mStarted;
|
PRPackedBool mStarted;
|
||||||
PRPackedBool mCached;
|
PRPackedBool mCached;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче