зеркало из https://github.com/mozilla/gecko-dev.git
Bug 940455 - Add LayerManager functonality to clear out a portion of the window for the OS to paint. r=roc,Bas
This commit is contained in:
Родитель
eba0d2158d
Коммит
205af94a59
|
@ -596,12 +596,19 @@ public:
|
|||
|
||||
bool IsInTransaction() const { return mInTransaction; }
|
||||
|
||||
virtual void AddRegionToClear(const nsIntRegion& aRegion)
|
||||
{
|
||||
mRegionToClear.Or(mRegionToClear, aRegion);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<Layer> mRoot;
|
||||
gfx::UserData mUserData;
|
||||
bool mDestroyed;
|
||||
bool mSnapEffectiveTransforms;
|
||||
|
||||
nsIntRegion mRegionToClear;
|
||||
|
||||
// Print interesting information about this into aTo. Internally
|
||||
// used to implement Dump*() and Log*().
|
||||
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
|
||||
|
@ -1335,6 +1342,7 @@ public:
|
|||
|
||||
virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
|
||||
|
||||
|
||||
void Mutated()
|
||||
{
|
||||
mManager->Mutated(this);
|
||||
|
|
|
@ -625,6 +625,16 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
|||
}
|
||||
|
||||
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
|
||||
if (!mRegionToClear.IsEmpty()) {
|
||||
AutoSetOperator op(mTarget, gfxContext::OPERATOR_CLEAR);
|
||||
nsIntRegionRectIterator iter(mRegionToClear);
|
||||
const nsIntRect *r;
|
||||
while ((r = iter.Next())) {
|
||||
mTarget->NewPath();
|
||||
mTarget->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
|
||||
mTarget->Fill();
|
||||
}
|
||||
}
|
||||
if (mWidget) {
|
||||
FlashWidgetUpdateArea(mTarget);
|
||||
}
|
||||
|
|
|
@ -709,6 +709,30 @@ LayerManagerD3D10::Render(EndTransactionFlags aFlags)
|
|||
|
||||
static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer();
|
||||
|
||||
if (!mRegionToClear.IsEmpty()) {
|
||||
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
gfx::Matrix4x4 transform;
|
||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform, 0, 64);
|
||||
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
|
||||
|
||||
ID3D10EffectTechnique *technique = effect()->GetTechniqueByName("RenderClearLayer");
|
||||
|
||||
nsIntRegionRectIterator iter(mRegionToClear);
|
||||
const nsIntRect *r;
|
||||
while ((r = iter.Next())) {
|
||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
||||
ShaderConstantRectD3D10(
|
||||
(float)r->x,
|
||||
(float)r->y,
|
||||
(float)r->width,
|
||||
(float)r->height)
|
||||
);
|
||||
|
||||
technique->GetPassByIndex(0)->Apply(0);
|
||||
device()->Draw(4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// See bug 630197 - we have some reasons to believe if an earlier call
|
||||
// returned an error, the upcoming present call may raise an exception.
|
||||
// This will check if any of the calls done recently has returned an error
|
||||
|
|
|
@ -448,6 +448,18 @@ technique10 RenderSolidColorLayer
|
|||
}
|
||||
}
|
||||
|
||||
technique10 RenderClearLayer
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
SetRasterizerState( LayerRast );
|
||||
SetBlendState( NoBlendDual, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
||||
SetGeometryShader( NULL );
|
||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShader() ) );
|
||||
}
|
||||
}
|
||||
|
||||
technique10 PrepareAlphaExtractionTextures
|
||||
{
|
||||
pass P0
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -261,6 +261,25 @@ LayerManagerD3D9::Render()
|
|||
|
||||
static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
|
||||
|
||||
if (!mRegionToClear.IsEmpty()) {
|
||||
D3DRECT* rects = new D3DRECT[mRegionToClear.GetNumRects()];
|
||||
nsIntRegionRectIterator iter(mRegionToClear);
|
||||
const nsIntRect *r;
|
||||
size_t i = 0;
|
||||
while ((r = iter.Next())) {
|
||||
rects[i].x1 = r->x;
|
||||
rects[i].y1 = r->y;
|
||||
rects[i].x2 = r->x + r->width;
|
||||
rects[i].y2 = r->y + r->height;
|
||||
i++;
|
||||
}
|
||||
|
||||
device()->Clear(i, rects, D3DCLEAR_TARGET,
|
||||
0x00000000, 0, 0);
|
||||
|
||||
delete [] rects;
|
||||
}
|
||||
|
||||
device()->EndScene();
|
||||
|
||||
if (!mTarget) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
struct nsRect;
|
||||
struct nsIntRect;
|
||||
struct nsIntSize;
|
||||
class nsIntRegion;
|
||||
struct nsFont;
|
||||
struct nsIntMargin;
|
||||
class nsPresContext;
|
||||
|
@ -29,8 +30,8 @@ class nsIWidget;
|
|||
// IID for the nsITheme interface
|
||||
// {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822}
|
||||
#define NS_ITHEME_IID \
|
||||
{ 0x3ca584e6, 0xdcd6, 0x485b, \
|
||||
{ 0x88, 0x8c, 0xe3, 0x47, 0x3d, 0xe4, 0xd9, 0x58 } }
|
||||
{ 0x2e49c679, 0x2130, 0x432c, \
|
||||
{ 0x92, 0xcb, 0xd4, 0x8e, 0x9a, 0xe2, 0x34, 0x75 } }
|
||||
// {D930E29B-6909-44e5-AB4B-AF10D6923705}
|
||||
#define NS_THEMERENDERER_CID \
|
||||
{ 0x9020805b, 0x14a3, 0x4125, \
|
||||
|
@ -62,7 +63,8 @@ public:
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect) = 0;
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Get the computed CSS border for the widget, in pixels.
|
||||
|
|
|
@ -3756,6 +3756,9 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
|||
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
|
||||
rc->Init(presContext->DeviceContext(), aContext);
|
||||
|
||||
nsIntRegion temp = builder->GetRegionToClear();
|
||||
builder->ResetRegionToClear();
|
||||
|
||||
if (shouldDrawRectsSeparately) {
|
||||
nsIntRegionRectIterator it(aRegionToDraw);
|
||||
while (const nsIntRect* iterRect = it.Next()) {
|
||||
|
@ -3797,6 +3800,10 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
|||
if (!aRegionToInvalidate.IsEmpty()) {
|
||||
aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds());
|
||||
}
|
||||
|
||||
aLayer->Manager()->AddRegionToClear(builder->GetRegionToClear());
|
||||
builder->ResetRegionToClear();
|
||||
builder->AddRegionToClear(temp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -2430,6 +2430,7 @@ nsDisplayThemedBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|||
PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx, const nsRect& aBounds,
|
||||
|
@ -2443,7 +2444,11 @@ nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
|
|||
theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance,
|
||||
&drawing);
|
||||
drawing.IntersectRect(drawing, aBounds);
|
||||
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing);
|
||||
nsIntRegion clear;
|
||||
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing, &clear);
|
||||
MOZ_ASSERT(clear.IsEmpty() || ReferenceFrame() == aBuilder->RootReferenceFrame(),
|
||||
"Can't add to clear region if we're transformed!");
|
||||
aBuilder->AddRegionToClear(clear);
|
||||
}
|
||||
|
||||
bool nsDisplayThemedBackground::IsWindowActive()
|
||||
|
|
|
@ -641,6 +641,10 @@ public:
|
|||
|
||||
DisplayListClipState& ClipState() { return mClipState; }
|
||||
|
||||
void AddRegionToClear(const nsIntRegion& aRegion) { mRegionToClear.Or(mRegionToClear, aRegion); }
|
||||
const nsIntRegion& GetRegionToClear() { return mRegionToClear; }
|
||||
void ResetRegionToClear() { mRegionToClear.SetEmpty(); }
|
||||
|
||||
private:
|
||||
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
|
||||
const nsRect& aDirtyRect);
|
||||
|
@ -674,6 +678,8 @@ private:
|
|||
const nsIFrame* mCachedReferenceFrame;
|
||||
nsPoint mCachedOffset;
|
||||
nsRegion mExcludedGlassRegion;
|
||||
// Area of the window (in pixels) to clear so the OS can draw them.
|
||||
nsIntRegion mRegionToClear;
|
||||
// The display item for the Windows window glass background, if any
|
||||
nsDisplayItem* mGlassDisplayItem;
|
||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||
|
|
|
@ -34,7 +34,8 @@ public:
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect);
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
|
|
|
@ -2080,7 +2080,8 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect)
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
|
|
|
@ -752,7 +752,8 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext,
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect)
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
{
|
||||
GtkWidgetState state;
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
|
|
|
@ -24,7 +24,8 @@ public:
|
|||
NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
nsIFrame* aFrame, uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect);
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
uint8_t aWidgetType, nsIntMargin* aResult);
|
||||
|
|
|
@ -1536,7 +1536,8 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect)
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
{
|
||||
HANDLE theme = GetTheme(aWidgetType);
|
||||
if (!theme)
|
||||
|
@ -1905,35 +1906,13 @@ RENDER_AGAIN:
|
|||
{
|
||||
// The caption buttons are drawn by the DWM, we just need to clear the area where they
|
||||
// are because we might have drawn something above them (like a background-image).
|
||||
ctx->Save();
|
||||
ctx->ResetClip();
|
||||
ctx->Translate(dr.TopLeft());
|
||||
|
||||
// Create a rounded rectangle to follow the buttons' look.
|
||||
gfxRect buttonbox1(0.0, 0.0, dr.Width(), dr.Height() - 2.0);
|
||||
gfxRect buttonbox2(1.0, dr.Height() - 2.0, dr.Width() - 1.0, 1.0);
|
||||
gfxRect buttonbox3(2.0, dr.Height() - 1.0, dr.Width() - 3.0, 1.0);
|
||||
|
||||
gfxContext::GraphicsOperator currentOp = ctx->CurrentOperator();
|
||||
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
|
||||
// Each rectangle is drawn individually because OPERATOR_CLEAR takes
|
||||
// the fallback path to cairo_d2d_acquire_dest if the area to fill
|
||||
// is a complex region.
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(buttonbox1, true);
|
||||
ctx->Fill();
|
||||
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(buttonbox2, true);
|
||||
ctx->Fill();
|
||||
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(buttonbox3, true);
|
||||
ctx->Fill();
|
||||
|
||||
ctx->Restore();
|
||||
ctx->SetOperator(currentOp);
|
||||
NS_ASSERTION(aRegionToClear, "Must have a clear region to set!");
|
||||
if (aRegionToClear) {
|
||||
// Create a rounded rectangle to follow the buttons' look.
|
||||
*aRegionToClear = nsIntRect(dr.X(), dr.Y(), dr.Width(), dr.Height() - 2.0);
|
||||
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 1.0, dr.YMost() - 2.0, dr.Width() - 1.0, 1.0));
|
||||
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 2.0, dr.YMost() - 1.0, dr.Width() - 3.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
|
|
|
@ -31,7 +31,8 @@ public:
|
|||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect);
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
|
|
Загрузка…
Ссылка в новой задаче