RenderFrameParent.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. * vim: sw=2 ts=8 et :
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  7. #include "base/basictypes.h"
  8. #include "BasicLayers.h"
  9. #include "gfxPrefs.h"
  10. #ifdef MOZ_ENABLE_D3D9_LAYER
  11. # include "LayerManagerD3D9.h"
  12. #endif //MOZ_ENABLE_D3D9_LAYER
  13. #include "mozilla/BrowserElementParent.h"
  14. #include "mozilla/EventForwards.h" // for Modifiers
  15. #include "mozilla/dom/ContentChild.h"
  16. #include "mozilla/dom/ContentParent.h"
  17. #include "mozilla/dom/TabChild.h"
  18. #include "mozilla/dom/TabParent.h"
  19. #include "mozilla/layers/APZCTreeManager.h"
  20. #include "mozilla/layers/APZThreadUtils.h"
  21. #include "mozilla/layers/CompositorBridgeParent.h"
  22. #include "mozilla/layers/LayerTransactionParent.h"
  23. #include "nsContentUtils.h"
  24. #include "nsFocusManager.h"
  25. #include "nsFrameLoader.h"
  26. #include "nsIObserver.h"
  27. #include "nsStyleStructInlines.h"
  28. #include "nsSubDocumentFrame.h"
  29. #include "nsView.h"
  30. #include "nsViewportFrame.h"
  31. #include "RenderFrameParent.h"
  32. #include "mozilla/gfx/GPUProcessManager.h"
  33. #include "mozilla/layers/LayerManagerComposite.h"
  34. #include "mozilla/layers/CompositorBridgeChild.h"
  35. #include "ClientLayerManager.h"
  36. #include "FrameLayerBuilder.h"
  37. using namespace mozilla::dom;
  38. using namespace mozilla::gfx;
  39. using namespace mozilla::layers;
  40. namespace mozilla {
  41. namespace layout {
  42. typedef FrameMetrics::ViewID ViewID;
  43. /**
  44. * Gets the layer-pixel offset of aContainerFrame's content rect top-left
  45. * from the nearest display item reference frame (which we assume will be inducing
  46. * a ContainerLayer).
  47. */
  48. static nsIntPoint
  49. GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
  50. {
  51. nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
  52. // Offset to the content rect in case we have borders or padding
  53. // Note that aContainerFrame could be a reference frame itself, so
  54. // we need to be careful here to ensure that we call ToReferenceFrame
  55. // on aContainerFrame and not its parent.
  56. nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
  57. aContainerFrame->GetContentRectRelativeToSelf().TopLeft();
  58. return frameOffset.ToNearestPixels(auPerDevPixel);
  59. }
  60. // Return true iff |aManager| is a "temporary layer manager". They're
  61. // used for small software rendering tasks, like drawWindow. That's
  62. // currently implemented by a BasicLayerManager without a backing
  63. // widget, and hence in non-retained mode.
  64. inline static bool
  65. IsTempLayerManager(LayerManager* aManager)
  66. {
  67. return (mozilla::layers::LayersBackend::LAYERS_BASIC == aManager->GetBackendType() &&
  68. !static_cast<BasicLayerManager*>(aManager)->IsRetained());
  69. }
  70. already_AddRefed<LayerManager>
  71. GetFrom(nsFrameLoader* aFrameLoader)
  72. {
  73. nsIDocument* doc = aFrameLoader->GetOwnerDoc();
  74. if (!doc) {
  75. return nullptr;
  76. }
  77. return nsContentUtils::LayerManagerForDocument(doc);
  78. }
  79. RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, bool* aSuccess)
  80. : mLayersId(0)
  81. , mFrameLoader(aFrameLoader)
  82. , mFrameLoaderDestroyed(false)
  83. , mAsyncPanZoomEnabled(false)
  84. , mInitted(false)
  85. {
  86. mInitted = Init(aFrameLoader);
  87. *aSuccess = mInitted;
  88. }
  89. RenderFrameParent::~RenderFrameParent()
  90. {}
  91. bool
  92. RenderFrameParent::Init(nsFrameLoader* aFrameLoader)
  93. {
  94. if (mInitted || !aFrameLoader) {
  95. return false;
  96. }
  97. mFrameLoader = aFrameLoader;
  98. RefPtr<LayerManager> lm = GetFrom(mFrameLoader);
  99. mAsyncPanZoomEnabled = lm && lm->AsyncPanZoomEnabled();
  100. TabParent* browser = TabParent::GetFrom(mFrameLoader);
  101. if (XRE_IsParentProcess()) {
  102. // Our remote frame will push layers updates to the compositor,
  103. // and we'll keep an indirect reference to that tree.
  104. browser->Manager()->AsContentParent()->AllocateLayerTreeId(browser, &mLayersId);
  105. if (lm && lm->AsClientLayerManager()) {
  106. if (!lm->AsClientLayerManager()->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId)) {
  107. return false;
  108. }
  109. }
  110. } else if (XRE_IsContentProcess()) {
  111. ContentChild::GetSingleton()->SendAllocateLayerTreeId(browser->Manager()->ChildID(), browser->GetTabId(), &mLayersId);
  112. if (!CompositorBridgeChild::Get()->SendNotifyChildCreated(mLayersId)) {
  113. return false;
  114. }
  115. }
  116. mInitted = true;
  117. return true;
  118. }
  119. bool
  120. RenderFrameParent::IsInitted()
  121. {
  122. return mInitted;
  123. }
  124. void
  125. RenderFrameParent::Destroy()
  126. {
  127. mFrameLoaderDestroyed = true;
  128. }
  129. already_AddRefed<Layer>
  130. RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
  131. nsIFrame* aFrame,
  132. LayerManager* aManager,
  133. const nsIntRect& aVisibleRect,
  134. nsDisplayItem* aItem,
  135. const ContainerLayerParameters& aContainerParameters)
  136. {
  137. MOZ_ASSERT(aFrame,
  138. "makes no sense to have a shadow tree without a frame");
  139. MOZ_ASSERT(!mContainer ||
  140. IsTempLayerManager(aManager) ||
  141. mContainer->Manager() == aManager,
  142. "retaining manager changed out from under us ... HELP!");
  143. if (IsTempLayerManager(aManager) ||
  144. (mContainer && mContainer->Manager() != aManager)) {
  145. // This can happen if aManager is a "temporary" manager, or if the
  146. // widget's layer manager changed out from under us. We need to
  147. // FIXME handle the former case somehow, probably with an API to
  148. // draw a manager's subtree. The latter is bad bad bad, but the the
  149. // MOZ_ASSERT() above will flag it. Returning nullptr here will just
  150. // cause the shadow subtree not to be rendered.
  151. if (!aContainerParameters.mForEventsAndPluginsOnly) {
  152. NS_WARNING("Remote iframe not rendered");
  153. }
  154. return nullptr;
  155. }
  156. uint64_t id = GetLayerTreeId();
  157. if (!id) {
  158. return nullptr;
  159. }
  160. RefPtr<Layer> layer =
  161. (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
  162. if (!layer) {
  163. layer = aManager->CreateRefLayer();
  164. }
  165. if (!layer) {
  166. // Probably a temporary layer manager that doesn't know how to
  167. // use ref layers.
  168. return nullptr;
  169. }
  170. static_cast<RefLayer*>(layer.get())->SetReferentId(id);
  171. nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
  172. // We can only have an offset if we're a child of an inactive
  173. // container, but our display item is LAYER_ACTIVE_FORCE which
  174. // forces all layers above to be active.
  175. MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
  176. gfx::Matrix4x4 m = gfx::Matrix4x4::Translation(offset.x, offset.y, 0.0);
  177. // Remote content can't be repainted by us, so we multiply down
  178. // the resolution that our container expects onto our container.
  179. m.PreScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
  180. layer->SetBaseTransform(m);
  181. return layer.forget();
  182. }
  183. void
  184. RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
  185. {
  186. MOZ_ASSERT(!mFrameLoader || mFrameLoader->GetOwnerContent() == aContent,
  187. "Don't build new map if owner is same!");
  188. RefPtr<LayerManager> lm = mFrameLoader ? GetFrom(mFrameLoader) : nullptr;
  189. // Perhaps the document containing this frame currently has no presentation?
  190. if (lm && lm->AsClientLayerManager()) {
  191. lm->AsClientLayerManager()->GetRemoteRenderer()->SendAdoptChild(mLayersId);
  192. FrameLayerBuilder::InvalidateAllLayers(lm);
  193. }
  194. }
  195. void
  196. RenderFrameParent::ActorDestroy(ActorDestroyReason why)
  197. {
  198. if (mLayersId != 0) {
  199. if (XRE_IsParentProcess()) {
  200. GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, OtherPid());
  201. } else if (XRE_IsContentProcess()) {
  202. ContentChild::GetSingleton()->SendDeallocateLayerTreeId(mLayersId);
  203. }
  204. }
  205. mFrameLoader = nullptr;
  206. }
  207. bool
  208. RenderFrameParent::RecvNotifyCompositorTransaction()
  209. {
  210. TriggerRepaint();
  211. return true;
  212. }
  213. void
  214. RenderFrameParent::TriggerRepaint()
  215. {
  216. nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent();
  217. if (!docFrame) {
  218. // Bad, but nothing we can do about it (XXX/cjones: or is there?
  219. // maybe bug 589337?). When the new frame is created, we'll
  220. // probably still be the current render frame and will get to draw
  221. // our content then. Or, we're shutting down and this update goes
  222. // to /dev/null.
  223. return;
  224. }
  225. docFrame->InvalidateLayer(nsDisplayItem::TYPE_REMOTE);
  226. }
  227. uint64_t
  228. RenderFrameParent::GetLayerTreeId() const
  229. {
  230. return mLayersId;
  231. }
  232. void
  233. RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
  234. nsSubDocumentFrame* aFrame,
  235. const nsDisplayListSet& aLists)
  236. {
  237. // We're the subdoc for <browser remote="true"> and it has
  238. // painted content. Display its shadow layer tree.
  239. DisplayListClipState::AutoSaveRestore clipState(aBuilder);
  240. nsPoint offset = aBuilder->ToReferenceFrame(aFrame);
  241. nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;
  242. clipState.ClipContentDescendants(bounds);
  243. aLists.Content()->AppendToTop(
  244. new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
  245. }
  246. void
  247. RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier)
  248. {
  249. RefPtr<LayerManager> lm = mFrameLoader ? GetFrom(mFrameLoader) : nullptr;
  250. // Perhaps the document containing this frame currently has no presentation?
  251. if (lm && lm->AsClientLayerManager()) {
  252. *aTextureFactoryIdentifier = lm->AsClientLayerManager()->GetTextureFactoryIdentifier();
  253. } else {
  254. *aTextureFactoryIdentifier = TextureFactoryIdentifier();
  255. }
  256. }
  257. void
  258. RenderFrameParent::TakeFocusForClickFromTap()
  259. {
  260. nsIFocusManager* fm = nsFocusManager::GetFocusManager();
  261. if (!fm) {
  262. return;
  263. }
  264. nsCOMPtr<nsIContent> owner = mFrameLoader->GetOwnerContent();
  265. if (!owner) {
  266. return;
  267. }
  268. nsCOMPtr<nsIDOMElement> element = do_QueryInterface(owner);
  269. if (!element) {
  270. return;
  271. }
  272. fm->SetFocus(element, nsIFocusManager::FLAG_BYMOUSE |
  273. nsIFocusManager::FLAG_BYTOUCH |
  274. nsIFocusManager::FLAG_NOSCROLL);
  275. }
  276. void
  277. RenderFrameParent::EnsureLayersConnected()
  278. {
  279. RefPtr<LayerManager> lm = GetFrom(mFrameLoader);
  280. if (!lm) {
  281. return;
  282. }
  283. ClientLayerManager* client = lm->AsClientLayerManager();
  284. if (!client) {
  285. return;
  286. }
  287. client->GetRemoteRenderer()->SendNotifyChildRecreated(mLayersId);
  288. }
  289. } // namespace layout
  290. } // namespace mozilla
  291. nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
  292. nsSubDocumentFrame* aFrame,
  293. RenderFrameParent* aRemoteFrame)
  294. : nsDisplayItem(aBuilder, aFrame)
  295. , mRemoteFrame(aRemoteFrame)
  296. , mEventRegionsOverride(EventRegionsOverride::NoOverride)
  297. {
  298. if (aBuilder->IsBuildingLayerEventRegions()) {
  299. bool frameIsPointerEventsNone =
  300. aFrame->StyleUserInterface()->GetEffectivePointerEvents(aFrame) ==
  301. NS_STYLE_POINTER_EVENTS_NONE;
  302. if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
  303. mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
  304. }
  305. if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresContext()->PresShell())) {
  306. mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
  307. }
  308. }
  309. }
  310. already_AddRefed<Layer>
  311. nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
  312. LayerManager* aManager,
  313. const ContainerLayerParameters& aContainerParameters)
  314. {
  315. int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
  316. nsIntRect visibleRect = GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
  317. visibleRect += aContainerParameters.mOffset;
  318. RefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, visibleRect, this, aContainerParameters);
  319. if (layer && layer->AsContainerLayer()) {
  320. layer->AsContainerLayer()->SetEventRegionsOverride(mEventRegionsOverride);
  321. }
  322. return layer.forget();
  323. }