Bug 724886: Push images from plugin code instead of pulling from nsObjectFrame. r=roc

This commit is contained in:
Bas Schouten 2012-02-08 16:34:27 +01:00
Родитель 76a9d4bafc
Коммит f708b773a5
13 изменённых файлов: 72 добавлений и 49 удалений

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

@ -295,7 +295,7 @@ PluginPRLibrary::HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,
#endif
nsresult
PluginPRLibrary::GetImage(NPP instance, ImageContainer* aContainer, Image** aImage)
PluginPRLibrary::GetImageContainer(NPP instance, ImageContainer** aContainer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

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

@ -142,7 +142,7 @@ public:
virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result);
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage);
virtual nsresult GetImageContainer(NPP instance, ImageContainer** aContainer);
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize);
NS_OVERRIDE virtual bool UseAsyncPainting() { return false; }
#if defined(XP_MACOSX)

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

@ -958,15 +958,15 @@ nsNPAPIPluginInstance::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
#endif
nsresult
nsNPAPIPluginInstance::GetImage(ImageContainer* aContainer, Image** aImage)
nsNPAPIPluginInstance::GetImageContainer(ImageContainer**aContainer)
{
*aImage = nsnull;
*aContainer = nsnull;
if (RUNNING != mRunning)
return NS_OK;
AutoPluginLibraryCall library(this);
return !library ? NS_ERROR_FAILURE : library->GetImage(&mNPP, aContainer, aImage);
return !library ? NS_ERROR_FAILURE : library->GetImageContainer(&mNPP, aContainer);
}
nsresult

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

@ -101,7 +101,7 @@ public:
bool ShouldCache();
nsresult IsWindowless(bool* isWindowless);
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetImage(ImageContainer* aContainer, Image** aImage);
nsresult GetImageContainer(ImageContainer **aContainer);
nsresult GetImageSize(nsIntSize* aSize);
nsresult NotifyPainted(void);
nsresult UseAsyncPainting(bool* aIsAsync);

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

@ -190,7 +190,7 @@ static void DrawPlugin(ImageContainer* aContainer, void* aPluginInstanceOwner)
{
nsObjectFrame* frame = static_cast<nsPluginInstanceOwner*>(aPluginInstanceOwner)->GetFrame();
if (frame) {
frame->UpdateImageLayer(aContainer, gfxRect(0,0,0,0));
frame->UpdateImageLayer(gfxRect(0,0,0,0));
}
}
@ -201,29 +201,28 @@ static void OnDestroyImage(void* aPluginInstanceOwner)
}
#endif // XP_MACOSX
bool
nsPluginInstanceOwner::SetCurrentImage(ImageContainer* aContainer)
already_AddRefed<ImageContainer>
nsPluginInstanceOwner::GetImageContainer()
{
if (mInstance) {
nsRefPtr<Image> image;
nsRefPtr<ImageContainer> container;
// Every call to nsIPluginInstance::GetImage() creates
// a new image. See nsIPluginInstance.idl.
mInstance->GetImage(aContainer, getter_AddRefs(image));
if (image) {
mInstance->GetImageContainer(getter_AddRefs(container));
if (container) {
#ifdef XP_MACOSX
if (image->GetFormat() == Image::MAC_IO_SURFACE && mObjectFrame) {
nsRefPtr<Image> image = container->GetCurrentImage();
if (image && image->GetFormat() == Image::MAC_IO_SURFACE && mObjectFrame) {
MacIOSurfaceImage *oglImage = static_cast<MacIOSurfaceImage*>(image.get());
NS_ADDREF_THIS();
oglImage->SetUpdateCallback(&DrawPlugin, this);
oglImage->SetDestroyCallback(&OnDestroyImage);
}
#endif
aContainer->SetCurrentImage(image);
return true;
return container.forget();
}
}
aContainer->SetCurrentImage(nsnull);
return false;
return nsnull;
}
void
@ -635,12 +634,9 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
// Each time an asynchronously-drawing plugin sends a new surface to display,
// InvalidateRect is called. We notify reftests that painting is up to
// date and update our ImageContainer with the new surface.
nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer();
nsRefPtr<ImageContainer> container;
mInstance->GetImageContainer(getter_AddRefs(container));
gfxIntSize oldSize(0, 0);
if (container) {
oldSize = container->GetCurrentSize();
SetCurrentImage(container);
}
#ifndef XP_MACOSX
// Windowed plugins should not be calling NPN_InvalidateRect, but

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

@ -275,8 +275,10 @@ public:
}
void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder);
// Return true if we set image with valid surface
bool SetCurrentImage(ImageContainer* aContainer);
// Returns the image container that has our currently displayed image.
already_AddRefed<ImageContainer> GetImageContainer();
/**
* Returns the bounds of the current async-rendered surface. This can only
* change in response to messages received by the event loop (i.e. not during

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

@ -626,7 +626,7 @@ PluginInstanceParent::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
#endif
nsresult
PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage)
PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
{
#ifdef XP_MACOSX
nsIOSurface* ioSurface = NULL;
@ -650,8 +650,14 @@ PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage)
}
#endif
ImageContainer *container = GetImageContainer();
if (!container) {
return NS_ERROR_FAILURE;
}
nsRefPtr<Image> image;
image = aContainer->CreateImage(&format, 1);
image = container->CreateImage(&format, 1);
if (!image) {
return NS_ERROR_FAILURE;
}
@ -663,7 +669,10 @@ PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage)
MacIOSurfaceImage::Data ioData;
ioData.mIOSurface = ioSurface;
ioImage->SetData(ioData);
*aImage = image.forget().get();
container->SetCurrentImage(ioImage);
NS_IF_ADDREF(container);
*aContainer = container;
return NS_OK;
}
#endif
@ -675,7 +684,10 @@ PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage)
cairoData.mSize = mFrontSurface->GetSize();
pluginImage->SetData(cairoData);
*aImage = image.forget().get();
container->SetCurrentImage(pluginImage);
NS_IF_ADDREF(container);
*aContainer = container;
return NS_OK;
}
@ -853,6 +865,17 @@ PluginInstanceParent::BackgroundDescriptor()
return SurfaceDescriptor();
}
ImageContainer*
PluginInstanceParent::GetImageContainer()
{
if (mImageContainer) {
return mImageContainer;
}
mImageContainer = LayerManager::CreateImageContainer();
return mImageContainer;
}
PPluginBackgroundDestroyerParent*
PluginInstanceParent::AllocPPluginBackgroundDestroyer()
{

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

@ -280,7 +280,7 @@ public:
AnswerPluginFocusChange(const bool& gotFocus);
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetImage(mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage);
nsresult GetImageContainer(mozilla::layers::ImageContainer** aContainer);
nsresult GetImageSize(nsIntSize* aSize);
#ifdef XP_MACOSX
nsresult IsRemoteDrawingCoreAnimation(bool *aDrawing);
@ -301,6 +301,9 @@ private:
void DestroyBackground();
SurfaceDescriptor BackgroundDescriptor() /*const*/;
typedef mozilla::layers::ImageContainer ImageContainer;
ImageContainer *GetImageContainer();
NS_OVERRIDE
virtual PPluginBackgroundDestroyerParent*
AllocPPluginBackgroundDestroyer();
@ -365,6 +368,8 @@ private:
// the consistency of the pixels in |mBackground|. A plugin may
// be able to observe partial updates to the background.
nsRefPtr<gfxASurface> mBackground;
nsRefPtr<ImageContainer> mImageContainer;
};

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

@ -100,7 +100,7 @@ public:
virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& aResult) = 0;
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) = 0;
virtual nsresult GetImageContainer(NPP instance, ImageContainer** aContainer) = 0;
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize) = 0;
virtual bool UseAsyncPainting() = 0;
#if defined(XP_MACOSX)

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

@ -687,12 +687,11 @@ PluginModuleParent::HandleGUIEvent(NPP instance,
#endif
nsresult
PluginModuleParent::GetImage(NPP instance,
mozilla::layers::ImageContainer* aContainer,
mozilla::layers::Image** aImage)
PluginModuleParent::GetImageContainer(NPP instance,
mozilla::layers::ImageContainer** aContainer)
{
PluginInstanceParent* i = InstCast(instance);
return !i ? NS_ERROR_FAILURE : i->GetImage(aContainer, aImage);
return !i ? NS_ERROR_FAILURE : i->GetImageContainer(aContainer);
}
nsresult

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

@ -262,7 +262,7 @@ private:
virtual bool HasRequiredFunctions();
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
virtual nsresult GetImage(NPP instance, mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage);
virtual nsresult GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer);
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize);
NS_OVERRIDE virtual bool UseAsyncPainting() { return true; }
NS_OVERRIDE

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

@ -1498,7 +1498,7 @@ nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem)
}
void
nsObjectFrame::UpdateImageLayer(ImageContainer* aContainer, const gfxRect& aRect)
nsObjectFrame::UpdateImageLayer(const gfxRect& aRect)
{
if (!mInstanceOwner) {
return;
@ -1507,10 +1507,13 @@ nsObjectFrame::UpdateImageLayer(ImageContainer* aContainer, const gfxRect& aRect
#ifdef XP_MACOSX
if (!mInstanceOwner->UseAsyncRendering()) {
mInstanceOwner->DoCocoaEventDrawRect(aRect, nsnull);
// This makes sure the image on the container is up to date.
// XXX - Eventually we probably just want to make sure DoCocoaEventDrawRect
// updates the image container, to make this truly use 'push' semantics
// too.
mInstanceOwner->GetImageContainer();
}
#endif
mInstanceOwner->SetCurrentImage(aContainer);
}
LayerState
@ -1552,16 +1555,11 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
return nsnull;
// Create image
nsRefPtr<ImageContainer> container = GetImageContainer();
nsRefPtr<ImageContainer> container = mInstanceOwner->GetImageContainer();
{
nsRefPtr<Image> current = container->GetCurrentImage();
if (!current) {
// Only set the current image if there isn't already one. If there is
// already one, InvalidateRect() will be keeping it up to date.
if (!mInstanceOwner->SetCurrentImage(container))
return nsnull;
}
if (!container) {
// This can occur if our instance is gone.
return nsnull;
}
gfxIntSize size = container->GetCurrentSize();
@ -1585,7 +1583,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "Bad layer type");
ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
UpdateImageLayer(container, r);
UpdateImageLayer(r);
imglayer->SetContainer(container);
gfxPattern::GraphicsFilter filter =

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

@ -158,7 +158,7 @@ public:
virtual bool ReflowFinished();
virtual void ReflowCallbackCanceled();
void UpdateImageLayer(ImageContainer* aContainer, const gfxRect& aRect);
void UpdateImageLayer(const gfxRect& aRect);
/**
* Builds either an ImageLayer or a ReadbackLayer, depending on the type