Bug 968833 - 1/2 - Make PLayerTransaction check actual layer types before casting - r=jrmuizel
authorBenoit Jacob <bjacob@mozilla.com>
Thu, 20 Feb 2014 11:40:55 -0500
changeset 170061 c342a70bdae4180c99452d333da30a4d92ed2066
parent 170060 3d3a0f471ca86ba45dd24f7d72d40bb8d65052ac
child 170062 e43eaa875fa020fc521bba802e01fd849e5cddda
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersjrmuizel
bugs968833
milestone30.0a1
Bug 968833 - 1/2 - Make PLayerTransaction check actual layer types before casting - r=jrmuizel
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/ShadowLayerParent.cpp
gfx/layers/ipc/ShadowLayerParent.h
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -263,17 +263,18 @@ LayerTransactionParent::RecvUpdate(const
       break;
     }
 
     // Attributes
     case Edit::TOpSetLayerAttributes: {
       MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
 
       const OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes();
-      Layer* layer = AsLayerComposite(osla)->AsLayer();
+      ShadowLayerParent* layerParent = AsLayerComposite(osla);
+      Layer* layer = layerParent->AsLayer();
       const LayerAttributes& attrs = osla.attrs();
 
       const CommonLayerAttributes& common = attrs.common();
       layer->SetVisibleRegion(common.visibleRegion());
       layer->SetEventRegions(common.eventRegions());
       layer->SetContentFlags(common.contentFlags());
       layer->SetOpacity(common.opacity());
       layer->SetClipRect(common.useClipRect() ? &common.clipRect() : nullptr);
@@ -301,66 +302,80 @@ LayerTransactionParent::RecvUpdate(const
       const SpecificLayerAttributes& specific = attrs.specific();
       switch (specific.type()) {
       case Specific::Tnull_t:
         break;
 
       case Specific::TThebesLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   thebes layer"));
 
-        ThebesLayerComposite* thebesLayer =
-          static_cast<ThebesLayerComposite*>(layer);
+        ThebesLayerComposite* thebesLayer = layerParent->AsThebesLayerComposite();
+        if (!thebesLayer) {
+          return false;
+        }
         const ThebesLayerAttributes& attrs =
           specific.get_ThebesLayerAttributes();
 
         thebesLayer->SetValidRegion(attrs.validRegion());
 
         break;
       }
       case Specific::TContainerLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   container layer"));
 
-        ContainerLayer* containerLayer =
-          static_cast<ContainerLayer*>(layer);
+        ContainerLayerComposite* containerLayer = layerParent->AsContainerLayerComposite();
+        if (!containerLayer) {
+          return false;
+        }
         const ContainerLayerAttributes& attrs =
           specific.get_ContainerLayerAttributes();
         containerLayer->SetFrameMetrics(attrs.metrics());
         containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale());
         containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
         break;
       }
-      case Specific::TColorLayerAttributes:
+      case Specific::TColorLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   color layer"));
 
-        static_cast<ColorLayer*>(layer)->SetColor(
-          specific.get_ColorLayerAttributes().color().value());
-        static_cast<ColorLayer*>(layer)->SetBounds(
-          specific.get_ColorLayerAttributes().bounds());
+        ColorLayerComposite* colorLayer = layerParent->AsColorLayerComposite();
+        if (!colorLayer) {
+          return false;
+        }
+        colorLayer->SetColor(specific.get_ColorLayerAttributes().color().value());
+        colorLayer->SetBounds(specific.get_ColorLayerAttributes().bounds());
         break;
-
-      case Specific::TCanvasLayerAttributes:
+      }
+      case Specific::TCanvasLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   canvas layer"));
 
-        static_cast<CanvasLayer*>(layer)->SetFilter(
-          specific.get_CanvasLayerAttributes().filter());
-        static_cast<CanvasLayerComposite*>(layer)->SetBounds(
-          specific.get_CanvasLayerAttributes().bounds());
+        CanvasLayerComposite* canvasLayer = layerParent->AsCanvasLayerComposite();
+        if (!canvasLayer) {
+          return false;
+        }
+        canvasLayer->SetFilter(specific.get_CanvasLayerAttributes().filter());
+        canvasLayer->SetBounds(specific.get_CanvasLayerAttributes().bounds());
         break;
-
-      case Specific::TRefLayerAttributes:
+      }
+      case Specific::TRefLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   ref layer"));
 
-        static_cast<RefLayer*>(layer)->SetReferentId(
-          specific.get_RefLayerAttributes().id());
+        RefLayerComposite* refLayer = layerParent->AsRefLayerComposite();
+        if (!refLayer) {
+          return false;
+        }
+        refLayer->SetReferentId(specific.get_RefLayerAttributes().id());
         break;
-
+      }
       case Specific::TImageLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   image layer"));
 
-        ImageLayer* imageLayer = static_cast<ImageLayer*>(layer);
+        ImageLayerComposite* imageLayer = layerParent->AsImageLayerComposite();
+        if (!imageLayer) {
+          return false;
+        }
         const ImageLayerAttributes& attrs = specific.get_ImageLayerAttributes();
         imageLayer->SetFilter(attrs.filter());
         imageLayer->SetScaleToSize(attrs.scaleToSize(), attrs.scaleMode());
         break;
       }
       default:
         NS_RUNTIMEABORT("not reached");
       }
@@ -377,49 +392,49 @@ LayerTransactionParent::RecvUpdate(const
 
       mRoot = AsLayerComposite(edit.get_OpSetRoot())->AsLayer();
       break;
     }
     case Edit::TOpInsertAfter: {
       MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
 
       const OpInsertAfter& oia = edit.get_OpInsertAfter();
-      ShadowContainer(oia)->AsContainer()->InsertAfter(
+      ShadowContainer(oia)->AsContainerLayerComposite()->InsertAfter(
         ShadowChild(oia)->AsLayer(), ShadowAfter(oia)->AsLayer());
       break;
     }
     case Edit::TOpAppendChild: {
       MOZ_LAYERS_LOG(("[ParentSide] AppendChild"));
 
       const OpAppendChild& oac = edit.get_OpAppendChild();
-      ShadowContainer(oac)->AsContainer()->InsertAfter(
+      ShadowContainer(oac)->AsContainerLayerComposite()->InsertAfter(
         ShadowChild(oac)->AsLayer(), nullptr);
       break;
     }
     case Edit::TOpRemoveChild: {
       MOZ_LAYERS_LOG(("[ParentSide] RemoveChild"));
 
       const OpRemoveChild& orc = edit.get_OpRemoveChild();
       Layer* childLayer = ShadowChild(orc)->AsLayer();
-      ShadowContainer(orc)->AsContainer()->RemoveChild(childLayer);
+      ShadowContainer(orc)->AsContainerLayerComposite()->RemoveChild(childLayer);
       break;
     }
     case Edit::TOpRepositionChild: {
       MOZ_LAYERS_LOG(("[ParentSide] RepositionChild"));
 
       const OpRepositionChild& orc = edit.get_OpRepositionChild();
-      ShadowContainer(orc)->AsContainer()->RepositionChild(
+      ShadowContainer(orc)->AsContainerLayerComposite()->RepositionChild(
         ShadowChild(orc)->AsLayer(), ShadowAfter(orc)->AsLayer());
       break;
     }
     case Edit::TOpRaiseToTopChild: {
       MOZ_LAYERS_LOG(("[ParentSide] RaiseToTopChild"));
 
       const OpRaiseToTopChild& rtc = edit.get_OpRaiseToTopChild();
-      ShadowContainer(rtc)->AsContainer()->RepositionChild(
+      ShadowContainer(rtc)->AsContainerLayerComposite()->RepositionChild(
         ShadowChild(rtc)->AsLayer(), nullptr);
       break;
     }
     case Edit::TCompositableOperation: {
       ReceiveCompositableUpdate(edit.get_CompositableOperation(),
                                 replyv);
       break;
     }
--- a/gfx/layers/ipc/ShadowLayerParent.cpp
+++ b/gfx/layers/ipc/ShadowLayerParent.cpp
@@ -5,16 +5,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ShadowLayerParent.h"
 #include "Layers.h"                     // for Layer, ContainerLayer
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
 
+#include "mozilla/layers/ThebesLayerComposite.h"
+#include "mozilla/layers/CanvasLayerComposite.h"
+#include "mozilla/layers/ColorLayerComposite.h"
+#include "mozilla/layers/ImageLayerComposite.h"
+#include "mozilla/layers/ContainerLayerComposite.h"
+
 namespace mozilla {
 namespace layers {
 
 ShadowLayerParent::ShadowLayerParent() : mLayer(nullptr)
 {
 }
 
 ShadowLayerParent::~ShadowLayerParent()
@@ -34,20 +40,62 @@ ShadowLayerParent::Destroy()
   // created, but just before the transaction in which Bind() would
   // have been called.  In that case, we'll ignore shadow-layers
   // transactions from there on and never get a layer here.
   if (mLayer) {
     mLayer->Disconnect();
   }
 }
 
-ContainerLayer*
-ShadowLayerParent::AsContainer() const
+ContainerLayerComposite*
+ShadowLayerParent::AsContainerLayerComposite() const
+{
+  return mLayer && mLayer->GetType() == Layer::TYPE_CONTAINER
+         ? static_cast<ContainerLayerComposite*>(mLayer.get())
+         : nullptr;
+}
+
+CanvasLayerComposite*
+ShadowLayerParent::AsCanvasLayerComposite() const
+{
+  return mLayer && mLayer->GetType() == Layer::TYPE_CANVAS
+         ? static_cast<CanvasLayerComposite*>(mLayer.get())
+         : nullptr;
+}
+
+ColorLayerComposite*
+ShadowLayerParent::AsColorLayerComposite() const
 {
-  return static_cast<ContainerLayer*>(AsLayer());
+  return mLayer && mLayer->GetType() == Layer::TYPE_COLOR
+         ? static_cast<ColorLayerComposite*>(mLayer.get())
+         : nullptr;
+}
+
+ImageLayerComposite*
+ShadowLayerParent::AsImageLayerComposite() const
+{
+  return mLayer && mLayer->GetType() == Layer::TYPE_IMAGE
+         ? static_cast<ImageLayerComposite*>(mLayer.get())
+         : nullptr;
+}
+
+RefLayerComposite*
+ShadowLayerParent::AsRefLayerComposite() const
+{
+  return mLayer && mLayer->GetType() == Layer::TYPE_REF
+         ? static_cast<RefLayerComposite*>(mLayer.get())
+         : nullptr;
+}
+
+ThebesLayerComposite*
+ShadowLayerParent::AsThebesLayerComposite() const
+{
+  return mLayer && mLayer->GetType() == Layer::TYPE_THEBES
+         ? static_cast<ThebesLayerComposite*>(mLayer.get())
+         : nullptr;
 }
 
 void
 ShadowLayerParent::ActorDestroy(ActorDestroyReason why)
 {
   switch (why) {
   case AncestorDeletion:
     NS_RUNTIMEABORT("shadow layer deleted out of order!");
--- a/gfx/layers/ipc/ShadowLayerParent.h
+++ b/gfx/layers/ipc/ShadowLayerParent.h
@@ -15,28 +15,41 @@
 
 namespace mozilla {
 namespace layers {
 
 class ContainerLayer;
 class Layer;
 class LayerManager;
 
+class CanvasLayerComposite;
+class ColorLayerComposite;
+class ContainerLayerComposite;
+class ImageLayerComposite;
+class RefLayerComposite;
+class ThebesLayerComposite;
+
 class ShadowLayerParent : public PLayerParent
 {
 public:
   ShadowLayerParent();
 
   virtual ~ShadowLayerParent();
 
   void Bind(Layer* layer);
   void Destroy();
 
   Layer* AsLayer() const { return mLayer; }
-  ContainerLayer* AsContainer() const;
+
+  ContainerLayerComposite* AsContainerLayerComposite() const;
+  CanvasLayerComposite* AsCanvasLayerComposite() const;
+  ColorLayerComposite* AsColorLayerComposite() const;
+  ImageLayerComposite* AsImageLayerComposite() const;
+  RefLayerComposite* AsRefLayerComposite() const;
+  ThebesLayerComposite* AsThebesLayerComposite() const;
 
 private:
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
   nsRefPtr<Layer> mLayer;
 };
 
 } // namespace layers