Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/client/ClientPaintedLayer.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "ClientPaintedLayer.h"
8
#include "ClientTiledPaintedLayer.h"     // for ClientTiledPaintedLayer
9
#include <stdint.h>                     // for uint32_t
10
#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
11
#include "client/ClientLayerManager.h"  // for ClientLayerManager, etc
12
#include "gfxContext.h"                 // for gfxContext
13
#include "gfx2DGlue.h"
14
#include "gfxEnv.h"                     // for gfxEnv
15
#include "gfxRect.h"                    // for gfxRect
16
#include "gfxPrefs.h"                   // for gfxPrefs
17
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
18
#include "mozilla/gfx/2D.h"             // for DrawTarget
19
#include "mozilla/gfx/DrawEventRecorder.h"
20
#include "mozilla/gfx/Matrix.h"         // for Matrix
21
#include "mozilla/gfx/Rect.h"           // for Rect, IntRect
22
#include "mozilla/gfx/Types.h"          // for Float, etc
23
#include "mozilla/layers/LayersTypes.h"
24
#include "mozilla/Preferences.h"
25
#include "nsCOMPtr.h"                   // for already_AddRefed
26
#include "nsISupportsImpl.h"            // for Layer::AddRef, etc
27
#include "nsRect.h"                     // for mozilla::gfx::IntRect
28
#include "PaintThread.h"
29
#include "ReadbackProcessor.h"
30
#include "RotatedBuffer.h"
31
32
namespace mozilla {
33
namespace layers {
34
35
using namespace mozilla::gfx;
36
37
bool
38
ClientPaintedLayer::EnsureContentClient()
39
0
{
40
0
  if (!mContentClient) {
41
0
    mContentClient = ContentClient::CreateContentClient(
42
0
      ClientManager()->AsShadowForwarder());
43
0
44
0
    if (!mContentClient) {
45
0
      return false;
46
0
    }
47
0
48
0
    mContentClient->Connect();
49
0
    ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
50
0
    MOZ_ASSERT(mContentClient->GetForwarder());
51
0
  }
52
0
53
0
  return true;
54
0
}
55
56
void
57
ClientPaintedLayer::UpdateContentClient(PaintState& aState)
58
0
{
59
0
  Mutated();
60
0
61
0
  AddToValidRegion(aState.mRegionToDraw);
62
0
63
0
  ContentClientRemoteBuffer *contentClientRemote =
64
0
      static_cast<ContentClientRemoteBuffer *>(mContentClient.get());
65
0
  MOZ_ASSERT(contentClientRemote->GetIPCHandle());
66
0
67
0
  // Hold(this) ensures this layer is kept alive through the current transaction
68
0
  // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer),
69
0
  // so deleting this Hold for whatever reason will break things.
70
0
  ClientManager()->Hold(this);
71
0
  contentClientRemote->Updated(aState.mRegionToDraw,
72
0
                               mVisibleRegion.ToUnknownRegion());
73
0
}
74
75
bool
76
ClientPaintedLayer::UpdatePaintRegion(PaintState& aState)
77
0
{
78
0
  SubtractFromValidRegion(aState.mRegionToInvalidate);
79
0
80
0
  if (!aState.mRegionToDraw.IsEmpty() && !ClientManager()->GetPaintedLayerCallback()) {
81
0
    ClientManager()->SetTransactionIncomplete();
82
0
    return false;
83
0
   }
84
0
85
0
   // The area that became invalid and is visible needs to be repainted
86
0
   // (this could be the whole visible area if our buffer switched
87
0
   // from RGB to RGBA, because we might need to repaint with
88
0
   // subpixel AA)
89
0
  aState.mRegionToInvalidate.And(aState.mRegionToInvalidate,
90
0
                                 GetLocalVisibleRegion().ToUnknownRegion());
91
0
  return true;
92
0
}
93
94
void
95
ClientPaintedLayer::FinishPaintState(PaintState& aState)
96
0
{
97
0
  if (aState.mAsyncTask && !aState.mAsyncTask->mCapture->IsEmpty()) {
98
0
    ClientManager()->SetQueuedAsyncPaints();
99
0
    PaintThread::Get()->QueuePaintTask(std::move(aState.mAsyncTask));
100
0
  }
101
0
}
102
103
uint32_t
104
ClientPaintedLayer::GetPaintFlags(ReadbackProcessor* aReadback)
105
0
{
106
0
  uint32_t flags = ContentClient::PAINT_CAN_DRAW_ROTATED;
107
0
  #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
108
0
   if (ClientManager()->CompositorMightResample()) {
109
0
     flags |= ContentClient::PAINT_WILL_RESAMPLE;
110
0
   }
111
0
   if (!(flags & ContentClient::PAINT_WILL_RESAMPLE)) {
112
0
     if (MayResample()) {
113
0
       flags |= ContentClient::PAINT_WILL_RESAMPLE;
114
0
     }
115
0
   }
116
0
  #endif
117
0
  if ((!aReadback || !UsedForReadback()) && PaintThread::Get()) {
118
0
    flags |= ContentClient::PAINT_ASYNC;
119
0
  }
120
0
  return flags;
121
0
}
122
123
void
124
ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback)
125
0
{
126
0
  AUTO_PROFILER_LABEL("ClientPaintedLayer::RenderLayerWithReadback", GRAPHICS);
127
0
  NS_ASSERTION(ClientManager()->InDrawing(),
128
0
               "Can only draw in drawing phase");
129
0
130
0
  RenderMaskLayers(this);
131
0
132
0
  if (!EnsureContentClient()) {
133
0
    return;
134
0
  }
135
0
136
0
  nsTArray<ReadbackProcessor::Update> readbackUpdates;
137
0
  nsIntRegion readbackRegion;
138
0
  if (aReadback && UsedForReadback()) {
139
0
    aReadback->GetPaintedLayerUpdates(this, &readbackUpdates);
140
0
  }
141
0
142
0
  uint32_t flags = GetPaintFlags(aReadback);
143
0
144
0
  PaintState state = mContentClient->BeginPaint(this, flags);
145
0
  if (!UpdatePaintRegion(state)) {
146
0
    mContentClient->EndPaint(state, nullptr);
147
0
    FinishPaintState(state);
148
0
    return;
149
0
  }
150
0
151
0
  bool didUpdate = false;
152
0
  RotatedBuffer::DrawIterator iter;
153
0
  while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) {
154
0
    SetAntialiasingFlags(this, target);
155
0
156
0
    RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
157
0
    MOZ_ASSERT(ctx); // already checked the target above
158
0
159
0
    if (!gfxEnv::SkipRasterization()) {
160
0
      ClientManager()->GetPaintedLayerCallback()(this,
161
0
                                                ctx,
162
0
                                                iter.mDrawRegion,
163
0
                                                iter.mDrawRegion,
164
0
                                                state.mClip,
165
0
                                                state.mRegionToInvalidate,
166
0
                                                ClientManager()->GetPaintedLayerCallbackData());
167
0
    }
168
0
169
0
    ctx = nullptr;
170
0
    mContentClient->ReturnDrawTarget(target);
171
0
    didUpdate = true;
172
0
  }
173
0
174
0
  mContentClient->EndPaint(state, &readbackUpdates);
175
0
  FinishPaintState(state);
176
0
177
0
  if (didUpdate) {
178
0
    UpdateContentClient(state);
179
0
  }
180
0
}
181
182
already_AddRefed<PaintedLayer>
183
ClientLayerManager::CreatePaintedLayer()
184
0
{
185
0
  return CreatePaintedLayerWithHint(NONE);
186
0
}
187
188
already_AddRefed<PaintedLayer>
189
ClientLayerManager::CreatePaintedLayerWithHint(PaintedLayerCreationHint aHint)
190
0
{
191
0
  NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
192
0
  if (gfxPlatform::GetPlatform()->UsesTiling()) {
193
0
    RefPtr<ClientTiledPaintedLayer> layer = new ClientTiledPaintedLayer(this, aHint);
194
0
    CREATE_SHADOW(Painted);
195
0
    return layer.forget();
196
0
  } else {
197
0
    RefPtr<ClientPaintedLayer> layer = new ClientPaintedLayer(this, aHint);
198
0
    CREATE_SHADOW(Painted);
199
0
    return layer.forget();
200
0
  }
201
0
}
202
203
void
204
ClientPaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
205
0
{
206
0
  PaintedLayer::PrintInfo(aStream, aPrefix);
207
0
  if (mContentClient) {
208
0
    aStream << "\n";
209
0
    nsAutoCString pfx(aPrefix);
210
0
    pfx += "  ";
211
0
    mContentClient->PrintInfo(aStream, pfx.get());
212
0
  }
213
0
}
214
215
} // namespace layers
216
} // namespace mozilla