Bug 1128225 (Part 3) - Add infrastructure for tracking draw results in geometry items. r=tn

This commit is contained in:
Seth Fowler 2015-02-04 13:50:56 -08:00
parent 91f9199732
commit 5ef2372989
3 changed files with 96 additions and 0 deletions

View File

@ -4732,6 +4732,31 @@ FrameLayerBuilder::DumpRetainedLayerTree(LayerManager* aManager, std::stringstre
aManager->Dump(aStream, "", aDumpHtml);
}
nsDisplayItemGeometry*
FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
{
typedef nsTArray<DisplayItemData*> DataArray;
// Retrieve the array of DisplayItemData associated with our frame.
FrameProperties properties = aItem->Frame()->Properties();
auto dataArray =
static_cast<DataArray*>(properties.Get(LayerManagerDataProperty()));
if (!dataArray) {
return nullptr;
}
// Find our display item data, if it exists, and return its geometry.
uint32_t itemPerFrameKey = aItem->GetPerFrameKey();
for (uint32_t i = 0; i < dataArray->Length(); i++) {
DisplayItemData* data = dataArray->ElementAt(i);
if (data->GetDisplayItemKey() == itemPerFrameKey) {
return data->GetGeometry();
}
}
return nullptr;
}
gfx::Rect
CalculateBounds(const nsTArray<DisplayItemClip::RoundedRect>& aRects, int32_t A2D)
{

View File

@ -275,6 +275,17 @@ public:
*/
static void DumpRetainedLayerTree(LayerManager* aManager, std::stringstream& aStream, bool aDumpHtml = false);
/**
* Returns the most recently allocated geometry item for the given display
* item.
*
* XXX(seth): The current implementation must iterate through all display
* items allocated for this display item's frame. This may lead to O(n^2)
* behavior in some situations.
*/
static nsDisplayItemGeometry* GetMostRecentGeometry(nsDisplayItem* aItem);
/******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/
/* These are only in the public section because they need
* to be called by file-scope helper functions in FrameLayerBuilder.cpp.
@ -398,6 +409,7 @@ public:
uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
Layer* GetLayer() { return mLayer; }
nsDisplayItemGeometry* GetGeometry() const { return mGeometry.get(); }
void Invalidate() { mIsInvalid = true; }
private:

View File

@ -7,6 +7,8 @@
#define NSDISPLAYLISTINVALIDATION_H_
#include "mozilla/Attributes.h"
#include "FrameLayerBuilder.h"
#include "imgIContainer.h"
#include "nsRect.h"
#include "nsColor.h"
#include "gfxRect.h"
@ -71,6 +73,63 @@ public:
nsRect mBorderRect;
};
/**
* nsImageGeometryMixin is a mixin for geometry items that draw images. Geometry
* items that include this mixin can track drawing results and use that
* information to inform invalidation decisions.
*
* This mixin uses CRTP; its template parameter should be the type of the class
* that is inheriting from it. See nsDisplayItemGenericImageGeometry for an
* example.
*/
template <typename T>
class nsImageGeometryMixin
{
public:
explicit nsImageGeometryMixin(nsDisplayItem* aItem)
: mLastDrawResult(mozilla::image::DrawResult::NOT_READY)
{
auto lastGeometry =
static_cast<T*>(mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem));
if (lastGeometry) {
mLastDrawResult = lastGeometry->LastDrawResult();
}
}
static void UpdateDrawResult(nsDisplayItem* aItem,
mozilla::image::DrawResult aResult)
{
auto lastGeometry =
static_cast<T*>(mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem));
if (lastGeometry) {
lastGeometry->mLastDrawResult = aResult;
}
}
mozilla::image::DrawResult LastDrawResult() const { return mLastDrawResult; }
private:
mozilla::image::DrawResult mLastDrawResult;
};
/**
* nsDisplayItemGenericImageGeometry is a generic geometry item class that
* includes nsImageGeometryMixin.
*
* This should be sufficient for most display items that draw images.
*/
class nsDisplayItemGenericImageGeometry
: public nsDisplayItemGenericGeometry
, public nsImageGeometryMixin<nsDisplayItemGenericImageGeometry>
{
public:
nsDisplayItemGenericImageGeometry(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder)
: nsDisplayItemGenericGeometry(aItem, aBuilder)
, nsImageGeometryMixin(aItem)
{ }
};
class nsDisplayItemBoundsGeometry : public nsDisplayItemGeometry
{
public: