bug 794038 pt 3 - plugins support for resolution change. r=bgirard

This commit is contained in:
Steven Michaud 2012-10-16 20:41:21 +01:00
parent d93ac204b8
commit 5038f543ad
21 changed files with 157 additions and 11 deletions

View File

@ -277,6 +277,13 @@ PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
*aDrawing = false;
return NS_OK;
}
nsresult
PluginPRLibrary::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
{
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
return NS_OK;
}
#endif
nsresult

View File

@ -114,6 +114,7 @@ public:
virtual bool IsOOP() MOZ_OVERRIDE { return false; }
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
#endif
virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE;
virtual nsresult BeginUpdateBackground(NPP instance,

View File

@ -1081,6 +1081,26 @@ nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing)
#endif
}
nsresult nsNPAPIPluginInstance::ContentsScaleFactorChanged(double aContentsScaleFactor)
{
#ifdef XP_MACOSX
if (!mPlugin)
return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
if (!library)
return NS_ERROR_FAILURE;
// We only need to call this if the plugin is running OOP.
if (!library->IsOOP())
return NS_OK;
return library->ContentsScaleFactorChanged(&mNPP, aContentsScaleFactor);
#else
return NS_ERROR_FAILURE;
#endif
}
nsresult
nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject)
{

View File

@ -78,6 +78,7 @@ public:
nsresult GetValueFromPlugin(NPPVariable variable, void* value);
nsresult GetDrawingModel(int32_t* aModel);
nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing);
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
nsresult GetJSObject(JSContext *cx, JSObject** outObject);
bool ShouldCache();
nsresult IsWindowless(bool* isWindowless);

View File

@ -1370,6 +1370,14 @@ bool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation()
return coreAnimation;
}
nsresult nsPluginInstanceOwner::ContentsScaleFactorChanged(double aContentsScaleFactor)
{
if (!mInstance) {
return NS_ERROR_NULL_POINTER;
}
return mInstance->ContentsScaleFactorChanged(aContentsScaleFactor);
}
NPEventModel nsPluginInstanceOwner::GetEventModel()
{
return mEventModel;

View File

@ -116,6 +116,7 @@ public:
NPDrawingModel GetDrawingModel();
bool IsRemoteDrawingCoreAnimation();
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
NPEventModel GetEventModel();
static void CARefresh(nsITimer *aTimer, void *aClosure);
void AddToCARefreshTimer();

View File

@ -118,6 +118,9 @@ child:
returns (int16_t handled);
// this is only used on windows to forward WM_WINDOWPOSCHANGE
async WindowPosChanged(NPRemoteEvent event);
// used on OS X to tell the child the contents scale factor
// of its parent has changed
async ContentsScaleFactorChanged(double aContentsScaleFactor);
// ********************** Async plugins rendering
// see https://wiki.mozilla.org/Gecko:AsyncPluginPainting

View File

@ -1013,6 +1013,24 @@ PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
#endif
}
bool
PluginInstanceChild::RecvContentsScaleFactorChanged(const double& aContentsScaleFactor)
{
#ifdef XP_MACOSX
mContentsScaleFactor = aContentsScaleFactor;
if (mShContext) {
// Release the shared context so that it is reallocated
// with the new size.
::CGContextRelease(mShContext);
mShContext = nullptr;
}
return true;
#else
NS_RUNTIMEABORT("ContentsScaleFactorChanged is an OSX-only message");
return false;
#endif
}
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
// Create a new window from NPWindow
bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
@ -3957,7 +3975,9 @@ PluginInstanceChild::SwapSurfaces()
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() !=
mDoubleBufferCARenderer.GetBackSurfaceWidth() ||
mDoubleBufferCARenderer.GetFrontSurfaceHeight() !=
mDoubleBufferCARenderer.GetBackSurfaceHeight())) {
mDoubleBufferCARenderer.GetBackSurfaceHeight() ||
mDoubleBufferCARenderer.GetFrontSurfaceContentsScaleFactor() !=
mDoubleBufferCARenderer.GetBackSurfaceContentsScaleFactor())) {
mDoubleBufferCARenderer.ClearFrontSurface();
}

View File

@ -126,6 +126,9 @@ protected:
virtual bool
RecvWindowPosChanged(const NPRemoteEvent& event) MOZ_OVERRIDE;
virtual bool
RecvContentsScaleFactorChanged(const double& aContentsScaleFactor) MOZ_OVERRIDE;
virtual bool
AnswerNPP_Destroy(NPError* result);

View File

@ -799,7 +799,14 @@ PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
return NS_OK;
}
#endif
nsresult
PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
{
bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
return rv ? NS_OK : NS_ERROR_FAILURE;
}
#endif // #ifdef XP_MACOSX
nsresult
PluginInstanceParent::SetBackgroundUnknown()

View File

@ -271,6 +271,7 @@ public:
nsresult GetImageSize(nsIntSize* aSize);
#ifdef XP_MACOSX
nsresult IsRemoteDrawingCoreAnimation(bool *aDrawing);
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
#endif
nsresult SetBackgroundUnknown();
nsresult BeginUpdateBackground(const nsIntRect& aRect,

View File

@ -73,6 +73,7 @@ public:
virtual bool IsOOP() = 0;
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) = 0;
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) = 0;
#endif
/**

View File

@ -1185,7 +1185,17 @@ PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
return i->IsRemoteDrawingCoreAnimation(aDrawing);
}
#endif
nsresult
PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
{
PluginInstanceParent* i = InstCast(instance);
if (!i)
return NS_ERROR_FAILURE;
return i->ContentsScaleFactorChanged(aContentsScaleFactor);
}
#endif // #if defined(XP_MACOSX)
bool
PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,

View File

@ -271,6 +271,7 @@ private:
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
#endif
#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
virtual nsresult HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,

View File

@ -50,12 +50,14 @@ public:
// Returns height in "display pixels". Multiply by
// mContentsScaleFactor to get device pixels.
size_t GetFrontSurfaceHeight();
double GetFrontSurfaceContentsScaleFactor();
// Returns width in "display pixels". Multiply by
// mContentsScaleFactor to get device pixels.
size_t GetBackSurfaceWidth();
// Returns height in "display pixels". Multiply by
// mContentsScaleFactor to get device pixels.
size_t GetBackSurfaceHeight();
double GetBackSurfaceContentsScaleFactor();
IOSurfaceID GetFrontSurfaceID();
bool HasBackSurface();

View File

@ -269,6 +269,14 @@ size_t nsDoubleBufferCARenderer::GetFrontSurfaceHeight() {
return mFrontSurface->GetHeight();
}
double nsDoubleBufferCARenderer::GetFrontSurfaceContentsScaleFactor() {
if (!HasFrontSurface()) {
return 1.0;
}
return mFrontSurface->GetContentsScaleFactor();
}
size_t nsDoubleBufferCARenderer::GetBackSurfaceWidth() {
if (!HasBackSurface()) {
return 0;
@ -285,6 +293,14 @@ size_t nsDoubleBufferCARenderer::GetBackSurfaceHeight() {
return mBackSurface->GetHeight();
}
double nsDoubleBufferCARenderer::GetBackSurfaceContentsScaleFactor() {
if (!HasBackSurface()) {
return 1.0;
}
return mBackSurface->GetContentsScaleFactor();
}
IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
if (!HasFrontSurface()) {
return 0;

View File

@ -743,6 +743,21 @@ void nsCARenderer::SetBounds(int aWidth, int aHeight) {
layer.contentsScale = mContentsScaleFactor;
}
}
} else {
// These settings are the default values. But they might have been
// changed as above if we were previously running in a HiDPI mode
// (i.e. if we just switched from that to a non-HiDPI mode).
[layer setAffineTransform:CGAffineTransformIdentity];
if ([layer respondsToSelector:@selector(setContentsScale:)]) {
#if !defined(MAC_OS_X_VERSION_10_7) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
Class CGBridgeLayerClass = ::NSClassFromString(@"CGBridgeLayer");
if (!CGBridgeLayerClass || ![layer isKindOfClass:CGBridgeLayerClass])
#endif
{
layer.contentsScale = 1.0;
}
}
}
[CATransaction commit];
@ -838,11 +853,19 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
int renderer_width = caRenderer.bounds.size.width / intScaleFactor;
int renderer_height = caRenderer.bounds.size.height / intScaleFactor;
if (renderer_width != aWidth || renderer_height != aHeight) {
if (renderer_width != aWidth || renderer_height != aHeight ||
mContentsScaleFactor != aContentsScaleFactor) {
// XXX: This should be optimized to not rescale the buffer
// if we are resizing down.
// caLayer is the CALayer* provided by the plugin, so we need to preserve
// it across the call to Destroy().
CALayer* caLayer = [caRenderer layer];
// mIOSurface is set by AttachIOSurface(), not by SetupRenderer(). So
// since it may have been set by a prior call to AttachIOSurface(), we
// need to preserve it across the call to Destroy().
mozilla::RefPtr<MacIOSurface> ioSurface = mIOSurface;
Destroy();
mIOSurface = ioSurface;
if (SetupRenderer(caLayer, aWidth, aHeight, aContentsScaleFactor,
mAllowOfflineRenderer) != NS_OK) {
return NS_ERROR_FAILURE;

View File

@ -2072,6 +2072,15 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
return fm->FocusPlugin(GetContent());
}
#ifdef XP_MACOSX
if (anEvent->message == NS_PLUGIN_RESOLUTION_CHANGED) {
double scaleFactor = 1.0;
mInstanceOwner->GetContentsScaleFactor(&scaleFactor);
mInstanceOwner->ContentsScaleFactorChanged(scaleFactor);
return NS_OK;
}
#endif
if (mInstanceOwner->SendNativeEvents() &&
NS_IS_PLUGIN_EVENT(anEvent)) {
*anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);

View File

@ -751,7 +751,8 @@ nsresult nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsIView* aView, nsEven
NS_IS_IME_RELATED_EVENT(aEvent) ||
NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) ||
aEvent->message == NS_PLUGIN_ACTIVATE ||
aEvent->message == NS_PLUGIN_FOCUS)) {
aEvent->message == NS_PLUGIN_FOCUS ||
aEvent->message == NS_PLUGIN_RESOLUTION_CHANGED)) {
while (view && !view->GetFrame()) {
view = view->GetParent();
}

View File

@ -778,13 +778,18 @@ nsChildView::BackingScaleFactorChanged()
mBackingScaleFactor = newScale;
if (!mWidgetListener || mWidgetListener->GetXULWindow()) {
return;
if (mWidgetListener && !mWidgetListener->GetXULWindow()) {
nsIPresShell* presShell = mWidgetListener->GetPresShell();
if (presShell) {
presShell->BackingScaleFactorChanged();
}
}
nsIPresShell* presShell = mWidgetListener->GetPresShell();
if (presShell) {
presShell->BackingScaleFactorChanged();
if (IsPluginView()) {
nsEventStatus status = nsEventStatus_eIgnore;
nsGUIEvent guiEvent(true, NS_PLUGIN_RESOLUTION_CHANGED, this);
guiEvent.time = PR_IntervalNow();
DispatchEvent(&guiEvent, status);
}
}

View File

@ -173,6 +173,11 @@ class nsHashKey;
#define NS_MOZ_USER_IDLE (NS_WINDOW_START + 67)
#define NS_MOZ_USER_ACTIVE (NS_WINDOW_START + 68)
// The resolution at which a plugin should draw has changed, for
// example as the result of changing from a HiDPI mode to a non-
// HiDPI mode.
#define NS_PLUGIN_RESOLUTION_CHANGED (NS_WINDOW_START + 69)
#define NS_MOUSE_MESSAGE_START 300
#define NS_MOUSE_MOVE (NS_MOUSE_MESSAGE_START)
#define NS_MOUSE_BUTTON_UP (NS_MOUSE_MESSAGE_START + 1)
@ -1778,7 +1783,8 @@ inline bool NS_IsEventUsingCoordinates(nsEvent* aEvent)
return !NS_IS_KEY_EVENT(aEvent) && !NS_IS_IME_RELATED_EVENT(aEvent) &&
!NS_IS_CONTEXT_MENU_KEY(aEvent) && !NS_IS_ACTIVATION_EVENT(aEvent) &&
!NS_IS_PLUGIN_EVENT(aEvent) &&
!NS_IS_CONTENT_COMMAND_EVENT(aEvent);
!NS_IS_CONTENT_COMMAND_EVENT(aEvent) &&
aEvent->message != NS_PLUGIN_RESOLUTION_CHANGED;
}
/**