Bug 579276. Part 5: Set CONTENT_NO_TEXT and CONTENT_NO_TEXT_OVER_TRANSPARENT flags. r=tnikkel
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 02 Sep 2010 21:18:40 +1200
changeset 51879 3e9ab38cc2518d9269379f13c18ccc96f1be53d3
parent 51878 022723860a7f2db3807667eee2f273ddd174d99f
child 51880 60c348050159e364b68cf162820c7e3701655563
push idunknown
push userunknown
push dateunknown
reviewerstnikkel
bugs579276
milestone2.0b6pre
Bug 579276. Part 5: Set CONTENT_NO_TEXT and CONTENT_NO_TEXT_OVER_TRANSPARENT flags. r=tnikkel
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -154,17 +154,18 @@ protected:
    * ThebesLayer in z-order. This reduces the number of layers and
    * makes it more likely a display item will be rendered to an opaque
    * layer, giving us the best chance of getting subpixel AA.
    */
   class ThebesLayerData {
   public:
     ThebesLayerData() :
       mActiveScrolledRoot(nsnull), mLayer(nsnull),
-      mIsSolidColorInVisibleRegion(PR_FALSE) {}
+      mIsSolidColorInVisibleRegion(PR_FALSE),
+      mHasText(PR_FALSE), mHasTextOverTransparent(PR_FALSE) {}
     /**
      * Record that an item has been added to the ThebesLayer, so we
      * need to update our regions.
      * @param aVisibleRect the area of the item that's visible
      * @param aDrawRect the area of the item that would be drawn if it
      * was completely visible
      * @param aOpaqueRect if non-null, the area of the item that's opaque.
      * We pass in a separate opaque rect because the opaque rect can be
@@ -223,16 +224,25 @@ protected:
      * If mIsSolidColorInVisibleRegion is true, this is the color of the visible
      * region.
      */
     nscolor      mSolidColor;
     /**
      * True if every pixel in mVisibleRegion will have color mSolidColor.
      */
     PRPackedBool mIsSolidColorInVisibleRegion;
+    /**
+     * True if there is any text visible in the layer.
+     */
+    PRPackedBool mHasText;
+    /**
+     * True if there is any text visible in the layer that's over
+     * transparent pixels in the layer.
+     */
+    PRPackedBool mHasTextOverTransparent;
   };
 
   /**
    * Grab the next recyclable ThebesLayer, or create one if there are no
    * more recyclable ThebesLayers. Does any necessary invalidation of
    * a recycled ThebesLayer, and sets up the transform on the ThebesLayer
    * to account for scrolling.
    */
@@ -834,17 +844,20 @@ ContainerState::PopThebesLayerData()
     NS_ASSERTION(userData, "where did our user data go?");
     if (userData->mForcedBackgroundColor != backgroundColor) {
       // Invalidate the entire target ThebesLayer since we're changing
       // the background color
       data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion());
     }
     userData->mForcedBackgroundColor = backgroundColor;
   }
-  PRUint32 flags = isOpaque ? Layer::CONTENT_OPAQUE : 0;
+  PRUint32 flags =
+    (isOpaque ? Layer::CONTENT_OPAQUE : 0) |
+    (data->mHasText ? 0 : Layer::CONTENT_NO_TEXT) |
+    (data->mHasTextOverTransparent ? 0 : Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT);
   layer->SetContentFlags(flags);
 
   if (lastIndex > 0) {
     // Since we're going to pop off the last ThebesLayerData, the
     // mVisibleAboveRegion of the second-to-last item will need to include
     // the regions of the last item.
     ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1];
     nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
@@ -855,16 +868,32 @@ ContainerState::PopThebesLayerData()
                                      data->mDrawAboveRegion);
     nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
                                      data->mDrawRegion);
   }
 
   mThebesLayerDataStack.RemoveElementAt(lastIndex);
 }
 
+static PRBool
+IsText(nsDisplayItem* aItem) {
+  switch (aItem->GetType()) {
+  case nsDisplayItem::TYPE_TEXT:
+  case nsDisplayItem::TYPE_BULLET:
+  case nsDisplayItem::TYPE_HEADER_FOOTER:
+  case nsDisplayItem::TYPE_MATHML_CHAR_FOREGROUND:
+#ifdef MOZ_XUL
+  case nsDisplayItem::TYPE_XUL_TEXT_BOX:
+#endif
+    return PR_TRUE;
+  default:
+    return PR_FALSE;
+  }
+}
+
 void
 ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
                                             nsDisplayItem* aItem,
                                             const nsIntRect& aVisibleRect,
                                             const nsIntRect& aDrawRect)
 {
   nscolor uniformColor;
   if (aItem->IsUniform(aBuilder, &uniformColor)) {
@@ -894,16 +923,21 @@ ContainerState::ThebesLayerData::Accumul
     // is a large opaque background at the bottom of z-order (e.g.,
     // a canvas background), so we need to make sure that the first rect
     // we see doesn't get discarded.
     nsIntRegion tmp;
     tmp.Or(mOpaqueRegion, aDrawRect);
     if (tmp.GetNumRects() <= 4) {
       mOpaqueRegion = tmp;
     }
+  } else if (IsText(aItem)) {
+    mHasText = PR_TRUE;
+    if (!mOpaqueRegion.Contains(aVisibleRect)) {
+      mHasTextOverTransparent = PR_TRUE;
+    }
   }
 }
 
 already_AddRefed<ThebesLayer>
 ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
                                    const nsIntRect& aVisibleRect,
                                    const nsIntRect& aDrawRect,
                                    nsIFrame* aActiveScrolledRoot)