mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 605618 Part 4: Map for storing views r=cjones
This commit is contained in:
parent
1b69189147
commit
871b660fda
@ -115,12 +115,14 @@
|
||||
#ifdef MOZ_IPC
|
||||
#include "ContentParent.h"
|
||||
#include "TabParent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
#endif
|
||||
|
||||
using namespace mozilla::layers;
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
@ -302,7 +304,6 @@ nsFrameLoader::nsFrameLoader(nsIContent *aOwner, PRBool aNetworkCreated)
|
||||
, mCurrentRemoteFrame(nsnull)
|
||||
, mRemoteBrowser(nsnull)
|
||||
#endif
|
||||
, mContentView(new nsContentView(aOwner, FrameMetrics::ROOT_SCROLL_ID))
|
||||
{
|
||||
}
|
||||
|
||||
@ -1284,6 +1285,9 @@ void
|
||||
nsFrameLoader::SetOwnerContent(nsIContent* aContent)
|
||||
{
|
||||
mOwnerContent = aContent;
|
||||
if (RenderFrameParent* rfp = GetCurrentRemoteFrame()) {
|
||||
rfp->OwnerContentChanged(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
@ -1975,16 +1979,51 @@ nsFrameLoader::GetContentViewsIn(float aXPx, float aYPx,
|
||||
PRUint32* aLength,
|
||||
nsIContentView*** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
*aLength = 0;
|
||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aXPx - aLeftSize);
|
||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aYPx - aTopSize);
|
||||
nscoord w = nsPresContext::CSSPixelsToAppUnits(aLeftSize + aRightSize) + 1;
|
||||
nscoord h = nsPresContext::CSSPixelsToAppUnits(aTopSize + aBottomSize) + 1;
|
||||
nsRect target(x, y, w, h);
|
||||
|
||||
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
||||
|
||||
nsTArray<ViewID> ids;
|
||||
nsLayoutUtils::GetRemoteContentIds(frame, target, ids, true);
|
||||
if (ids.Length() == 0 || !GetCurrentRemoteFrame()) {
|
||||
*aResult = nsnull;
|
||||
*aLength = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIContentView** result = reinterpret_cast<nsIContentView**>(
|
||||
NS_Alloc(ids.Length() * sizeof(nsIContentView*)));
|
||||
|
||||
for (PRUint32 i = 0; i < ids.Length(); i++) {
|
||||
nsIContentView* view = GetCurrentRemoteFrame()->GetContentView(ids[i]);
|
||||
NS_ABORT_IF_FALSE(view, "Retrieved ID from RenderFrameParent, it should be valid!");
|
||||
nsRefPtr<nsIContentView>(view).forget(&result[i]);
|
||||
}
|
||||
|
||||
*aResult = result;
|
||||
*aLength = ids.Length();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetRootContentView(nsIContentView** aContentView)
|
||||
{
|
||||
nsRefPtr<nsIContentView>(GetContentView()).forget(aContentView);
|
||||
return NS_OK;
|
||||
RenderFrameParent* rfp = GetCurrentRemoteFrame();
|
||||
if (!rfp) {
|
||||
*aContentView = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsContentView* view = rfp->GetContentView();
|
||||
NS_ABORT_IF_FALSE(view, "Should always be able to create root scrollable!");
|
||||
nsRefPtr<nsIContentView>(view).forget(aContentView);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -272,8 +272,7 @@ public:
|
||||
#endif
|
||||
nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
|
||||
|
||||
nsContentView* GetContentView() { return mContentView; }
|
||||
|
||||
nsIContent* GetOwnerContent() { return mOwnerContent; }
|
||||
void SetOwnerContent(nsIContent* aContent);
|
||||
|
||||
private:
|
||||
@ -338,8 +337,6 @@ private:
|
||||
TabParent* mRemoteBrowser;
|
||||
#endif
|
||||
|
||||
nsRefPtr<nsContentView> mContentView;
|
||||
|
||||
// See nsIFrameLoader.idl. Short story, if !(mRenderMode &
|
||||
// RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
|
||||
// favor of what content tells.
|
||||
|
@ -55,6 +55,9 @@ using namespace mozilla::layers;
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
typedef RenderFrameParent::ViewMap ViewMap;
|
||||
|
||||
static void
|
||||
AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
|
||||
nsIFrame* aContainedFrame)
|
||||
@ -66,6 +69,14 @@ AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
|
||||
"Expected frame to be in top-level chrome document");
|
||||
}
|
||||
|
||||
// Return view for given ID in aArray, NULL if not found.
|
||||
static nsContentView*
|
||||
FindViewForId(const ViewMap& aMap, ViewID aId)
|
||||
{
|
||||
ViewMap::const_iterator iter = aMap.find(aId);
|
||||
return iter != aMap.end() ? iter->second : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
AssertValidContainerOfShadowTree(ContainerLayer* aContainer,
|
||||
Layer* aShadowRoot)
|
||||
@ -179,10 +190,65 @@ IsTempLayerManager(LayerManager* aManager)
|
||||
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
|
||||
}
|
||||
|
||||
// Recursively create a new array of scrollables, preserving any scrollables
|
||||
// that are still in the layer tree.
|
||||
//
|
||||
// aXScale and aYScale are used to calculate any values that need to be in
|
||||
// chrome-document CSS pixels and aren't part of the rendering loop, such as
|
||||
// the initial scroll offset for a new view.
|
||||
static void
|
||||
BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
||||
nsFrameLoader* aFrameLoader, Layer* aLayer,
|
||||
float aXScale = 1, float aYScale = 1)
|
||||
{
|
||||
if (!aLayer->GetFirstChild())
|
||||
return;
|
||||
|
||||
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
const ViewID scrollId = metrics.mScrollId;
|
||||
|
||||
nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
|
||||
->PresContext()->AppUnitsPerDevPixel();
|
||||
nsContentView* view = FindViewForId(oldContentViews, scrollId);
|
||||
if (view) {
|
||||
// View already exists. Be sure to propagate scales for any values
|
||||
// that need to be calculated something in chrome-doc CSS pixels.
|
||||
ViewConfig config = view->GetViewConfig();
|
||||
aXScale *= config.mXScale;
|
||||
aYScale *= config.mYScale;
|
||||
view->mOwnerContent = aFrameLoader->GetOwnerContent();
|
||||
} else {
|
||||
// View doesn't exist, so generate one. We start the view scroll offset at
|
||||
// the same position as the framemetric's scroll offset from the layer.
|
||||
// The default scale is 1, so no need to propagate scale down.
|
||||
ViewConfig config;
|
||||
config.mScrollOffset = nsPoint(
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.x, auPerDevPixel) * aXScale,
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.y, auPerDevPixel) * aYScale);
|
||||
view = new nsContentView(aFrameLoader->GetOwnerContent(), scrollId, config);
|
||||
}
|
||||
|
||||
newContentViews.insert(ViewMap::value_type(scrollId, view));
|
||||
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
const gfx3DMatrix transform = aLayer->GetTransform();
|
||||
aXScale *= transform._11;
|
||||
aYScale *= transform._22;
|
||||
BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
|
||||
aXScale, aYScale);
|
||||
}
|
||||
}
|
||||
|
||||
RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader)
|
||||
: mFrameLoader(aFrameLoader)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFrameLoader, "Need a frameloader here");
|
||||
mContentViews.insert(ViewMap::value_type(
|
||||
FrameMetrics::ROOT_SCROLL_ID,
|
||||
new nsContentView(aFrameLoader->GetOwnerContent(), FrameMetrics::ROOT_SCROLL_ID)
|
||||
));
|
||||
}
|
||||
|
||||
RenderFrameParent::~RenderFrameParent()
|
||||
@ -202,11 +268,22 @@ RenderFrameParent::Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
nsContentView*
|
||||
RenderFrameParent::GetContentView(ViewID aId)
|
||||
{
|
||||
return FindViewForId(mContentViews, aId);
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ShadowLayersUpdated()
|
||||
{
|
||||
mFrameLoader->SetCurrentRemoteFrame(this);
|
||||
|
||||
// View map must only contain views that are associated with the current
|
||||
// shadow layer tree. We must always update the map when shadow layers
|
||||
// are updated.
|
||||
BuildViewMap();
|
||||
|
||||
nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent();
|
||||
if (!docFrame) {
|
||||
// Bad, but nothing we can do about it (XXX/cjones: or is there?
|
||||
@ -286,7 +363,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
float shadowXScale, shadowYScale;
|
||||
ComputeShadowTreeTransform(aFrame,
|
||||
shadowRoot->GetFrameMetrics(),
|
||||
mFrameLoader->GetContentView()->GetViewConfig(),
|
||||
GetContentView()->GetViewConfig(),
|
||||
aBuilder,
|
||||
&shadowTranslation,
|
||||
&shadowXScale, &shadowYScale);
|
||||
@ -299,6 +376,14 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
return nsRefPtr<Layer>(mContainer).forget();
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mFrameLoader->GetOwnerContent() == aContent,
|
||||
"Don't build new map if owner is same!");
|
||||
BuildViewMap();
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
@ -341,6 +426,34 @@ RenderFrameParent::DeallocPLayers(PLayersParent* aLayers)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::BuildViewMap()
|
||||
{
|
||||
ViewMap newContentViews;
|
||||
if (GetRootLayer()) {
|
||||
// Some of the content views in our hash map may no longer be active. To
|
||||
// tag them as inactive and to remove any chance of them using a dangling
|
||||
// pointer, we set mContentView to NULL.
|
||||
//
|
||||
// BuildViewMap will restore mOwnerContent if the content view is still
|
||||
// in our hash table.
|
||||
|
||||
for (ViewMap::const_iterator iter = mContentViews.begin();
|
||||
iter != mContentViews.end();
|
||||
++iter) {
|
||||
iter->second->mOwnerContent = NULL;
|
||||
}
|
||||
|
||||
mozilla::layout::BuildViewMap(mContentViews, newContentViews, mFrameLoader, GetRootLayer());
|
||||
}
|
||||
|
||||
// Root scrollable layer might not be around yet. Don't accidentally delete
|
||||
// our view for it.
|
||||
if (!newContentViews.empty()) {
|
||||
mContentViews = newContentViews;
|
||||
}
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
RenderFrameParent::GetLayerManager() const
|
||||
{
|
||||
|
@ -43,9 +43,11 @@
|
||||
|
||||
#include "mozilla/layout/PRenderFrameParent.h"
|
||||
|
||||
#include <map>
|
||||
#include "nsDisplayList.h"
|
||||
#include "Layers.h"
|
||||
|
||||
class nsContentView;
|
||||
class nsFrameLoader;
|
||||
class nsSubDocumentFrame;
|
||||
|
||||
@ -64,13 +66,22 @@ class RenderFrameParent : public PRenderFrameParent
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layers::ShadowLayersParent ShadowLayersParent;
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
|
||||
public:
|
||||
typedef std::map<ViewID, nsRefPtr<nsContentView> > ViewMap;
|
||||
|
||||
RenderFrameParent(nsFrameLoader* aFrameLoader);
|
||||
virtual ~RenderFrameParent();
|
||||
|
||||
void Destroy();
|
||||
|
||||
/**
|
||||
* Helper function for getting a non-owning reference to a scrollable.
|
||||
* @param aId The ID of the frame.
|
||||
*/
|
||||
nsContentView* GetContentView(ViewID aId = FrameMetrics::ROOT_SCROLL_ID);
|
||||
|
||||
void ShadowLayersUpdated();
|
||||
|
||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
@ -83,6 +94,8 @@ public:
|
||||
LayerManager* aManager,
|
||||
const nsIntRect& aVisibleRect);
|
||||
|
||||
void OwnerContentChanged(nsIContent* aContent);
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
@ -90,12 +103,18 @@ protected:
|
||||
NS_OVERRIDE virtual bool DeallocPLayers(PLayersParent* aLayers);
|
||||
|
||||
private:
|
||||
void BuildViewMap();
|
||||
|
||||
LayerManager* GetLayerManager() const;
|
||||
ShadowLayersParent* GetShadowLayers() const;
|
||||
ContainerLayer* GetRootLayer() const;
|
||||
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
nsRefPtr<ContainerLayer> mContainer;
|
||||
|
||||
// This contains the views for all the scrollable frames currently in the
|
||||
// painted region of our remote content.
|
||||
ViewMap mContentViews;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
|
Loading…
Reference in New Issue
Block a user