Bug 570620, part o: Connect the dots to enable drawing remote frames for <browser remote>: create the frame on the content side, insert a display item for it in compositor-side SubdocFrame, and use IPC-enabled layer managers to make it all work. r=mats sr=roc

This commit is contained in:
Chris Jones 2010-08-20 18:24:41 -05:00
Родитель 0e3d3aaf97
Коммит f22350f2bc
7 изменённых файлов: 119 добавлений и 16 удалений

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

@ -39,8 +39,10 @@
#include "TabChild.h"
#include "mozilla/dom/PContentChild.h"
#include "mozilla/dom/PContentDialogChild.h"
#include "mozilla/layers/PLayersChild.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "BasicLayers.h"
#include "nsIWebBrowser.h"
#include "nsIWebBrowserSetup.h"
#include "nsEmbedCID.h"
@ -89,6 +91,7 @@
#include "nsIView.h"
using namespace mozilla::dom;
using namespace mozilla::layers;
using namespace mozilla::layout;
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
@ -112,7 +115,8 @@ public:
TabChild::TabChild(PRUint32 aChromeFlags)
: mTabChildGlobal(nsnull)
: mRemoteFrame(nsnull)
, mTabChildGlobal(nsnull)
, mChromeFlags(aChromeFlags)
{
printf("creating %d!\n", NS_IsMainThread());
@ -412,8 +416,17 @@ TabChild::DestroyWindow()
if (baseWindow)
baseWindow->Destroy();
if (mWidget)
// NB: the order of mWidget->Destroy() and mRemoteFrame->Destroy()
// is important: we want to kill off remote layers before their
// frames
if (mWidget) {
mWidget->Destroy();
}
if (mRemoteFrame) {
mRemoteFrame->Destroy();
mRemoteFrame = nsnull;
}
}
void
@ -603,17 +616,9 @@ TabChild::RecvShow(const nsIntSize& size)
return false;
}
mWidget = nsIWidget::CreatePuppetWidget();
if (!mWidget) {
NS_ERROR("couldn't create fake widget");
if (!InitWidget(size)) {
return false;
}
mWidget->Create(
nsnull, 0, // no parents
nsIntRect(nsIntPoint(0, 0), size),
nsnull, // HandleWidgetEvent
nsnull // nsIDeviceContext
);
baseWindow->InitWindow(0, mWidget,
0, 0, size.width, size.height);
@ -1127,6 +1132,53 @@ TabChild::InitTabChildGlobal()
return true;
}
bool
TabChild::InitWidget(const nsIntSize& size)
{
NS_ABORT_IF_FALSE(!mWidget && !mRemoteFrame, "CreateWidget twice?");
mWidget = nsIWidget::CreatePuppetWidget();
if (!mWidget) {
NS_ERROR("couldn't create fake widget");
return false;
}
mWidget->Create(
nsnull, 0, // no parents
nsIntRect(nsIntPoint(0, 0), size),
nsnull, // HandleWidgetEvent
nsnull // nsIDeviceContext
);
RenderFrameChild* remoteFrame =
static_cast<RenderFrameChild*>(SendPRenderFrameConstructor());
if (!remoteFrame) {
NS_WARNING("failed to construct RenderFrame");
return false;
}
NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(),
"shouldn't have a shadow manager yet");
PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor();
if (!shadowManager) {
NS_WARNING("failed to construct LayersChild");
// This results in |remoteFrame| being deleted.
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
LayerManager* lm = mWidget->GetLayerManager();
NS_ABORT_IF_FALSE(LayerManager::LAYERS_BASIC == lm->GetBackendType(),
"content processes should only be using BasicLayers");
BasicShadowLayerManager* bslm = static_cast<BasicShadowLayerManager*>(lm);
NS_ABORT_IF_FALSE(!bslm->HasShadowManager(),
"PuppetWidget shouldn't have shadow manager yet");
bslm->SetShadowManager(shadowManager);
mRemoteFrame = remoteFrame;
return true;
}
static bool
SendSyncMessageToParent(void* aCallbackData,
const nsAString& aMessage,

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

@ -36,8 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_tabs_TabChild_h
#define mozilla_tabs_TabChild_h
#ifndef mozilla_dom_TabChild_h
#define mozilla_dom_TabChild_h
#ifndef _IMPL_NS_LAYOUT
#include "mozilla/dom/PBrowserChild.h"
@ -79,6 +79,10 @@
struct gfxMatrix;
namespace mozilla {
namespace layout {
class RenderFrameChild;
}
namespace dom {
class TabChild;
@ -155,6 +159,8 @@ class TabChild : public PBrowserChild,
public nsIDialogCreator,
public nsITabChild
{
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
public:
TabChild(PRUint32 aChromeFlags);
virtual ~TabChild();
@ -302,10 +308,12 @@ private:
void ActorDestroy(ActorDestroyReason why);
bool InitTabChildGlobal();
bool InitWidget(const nsIntSize& size);
void DestroyWindow();
nsCOMPtr<nsIWebNavigation> mWebNav;
nsCOMPtr<nsIWidget> mWidget;
RenderFrameChild* mRemoteFrame;
TabChildGlobal* mTabChildGlobal;
PRUint32 mChromeFlags;
@ -334,4 +342,4 @@ GetTabChildFrom(nsIPresShell* aPresShell)
}
}
#endif // mozilla_tabs_TabChild_h
#endif // mozilla_dom_TabChild_h

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

@ -46,12 +46,16 @@
#include "mozilla/unused.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "gfxSharedImageSurface.h"
#include "ImageLayers.h"
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
using mozilla::layout::RenderFrameParent;
namespace mozilla {
namespace layers {
@ -371,6 +375,8 @@ ShadowLayersParent::RecvUpdate(const nsTArray<Edit>& cset,
reply->AppendElements(&replyv.front(), replyv.size());
}
Frame()->ShadowLayersUpdated();
return true;
}
@ -387,5 +393,11 @@ ShadowLayersParent::DeallocPLayer(PLayerParent* actor)
return true;
}
RenderFrameParent*
ShadowLayersParent::Frame()
{
return static_cast<RenderFrameParent*>(Manager());
}
} // namespace layers
} // namespace mozilla

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

@ -44,6 +44,11 @@
#include "mozilla/layers/PLayersParent.h"
namespace mozilla {
namespace layout {
class RenderFrameParent;
}
namespace layers {
class Layer;
@ -51,6 +56,7 @@ class ShadowLayerManager;
class ShadowLayersParent : public PLayersParent
{
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
typedef nsTArray<Edit> EditArray;
typedef nsTArray<EditReply> EditReplyArray;
@ -70,6 +76,8 @@ protected:
NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor);
private:
RenderFrameParent* Frame();
nsRefPtr<ShadowLayerManager> mLayerManager;
// Hold the root because it might be grafted under various
// containers in the "real" layer tree

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

@ -42,6 +42,11 @@
* as <frame>, <iframe>, and some <object>s
*/
#ifdef MOZ_IPC
#include "mozilla/layout/RenderFrameParent.h"
using mozilla::layout::RenderFrameParent;
#endif
#include "nsCOMPtr.h"
#include "nsLeafFrame.h"
#include "nsGenericHTMLElement.h"
@ -374,7 +379,20 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef MOZ_IPC
nsFrameLoader* frameLoader = FrameLoader();
if (frameLoader) {
RenderFrameParent* rfp = frameLoader->GetCurrentRemoteFrame();
if (rfp) {
// We're the subdoc for <browser remote="true"> and it has
// painted content. Display its shadow layer tree.
return aLists.Content()
->AppendNewToTop(new (aBuilder) nsDisplayRemote(this, rfp));
}
}
#endif
if (!mInnerView)
return NS_OK;
nsIView* subdocView = mInnerView->GetFirstChild();

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

@ -110,6 +110,7 @@ PuppetWidget::Create(nsIWidget *aParent,
PuppetWidget* parent = static_cast<PuppetWidget*>(aParent);
if (parent) {
parent->SetChild(this);
mLayerManager = parent->GetLayerManager();
}
else {
Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, PR_FALSE);
@ -267,7 +268,7 @@ LayerManager*
PuppetWidget::GetLayerManager()
{
if (!mLayerManager) {
mLayerManager = new BasicLayerManager(this);
mLayerManager = new BasicShadowLayerManager(this);
}
return mLayerManager;
}

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

@ -784,7 +784,11 @@ LayerManager* nsBaseWidget::GetLayerManager()
}
}
if (!mLayerManager) {
#if !defined(MOZ_IPC)
mLayerManager = new BasicLayerManager(this);
#else
mLayerManager = new BasicShadowLayerManager(this);
#endif
}
}
return mLayerManager;