Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/SharedPlanarYCbCrImage.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 "SharedPlanarYCbCrImage.h"
8
#include <stddef.h>                     // for size_t
9
#include <stdio.h>                      // for printf
10
#include "gfx2DGlue.h"                  // for Moz2D transition helpers
11
#include "ISurfaceAllocator.h"          // for ISurfaceAllocator, etc
12
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
13
#include "mozilla/gfx/Types.h"          // for SurfaceFormat::SurfaceFormat::YUV
14
#include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
15
#include "mozilla/layers/ImageClient.h"  // for ImageClient
16
#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
17
#include "mozilla/layers/TextureClient.h"
18
#include "mozilla/layers/TextureClientRecycleAllocator.h"
19
#include "mozilla/layers/BufferTexture.h"
20
#include "mozilla/layers/ImageDataSerializer.h"
21
#include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
22
#include "mozilla/mozalloc.h"           // for operator delete
23
#include "nsISupportsImpl.h"            // for Image::AddRef
24
#include "mozilla/ipc/Shmem.h"
25
26
namespace mozilla {
27
namespace layers {
28
29
using namespace mozilla::ipc;
30
31
SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
32
  : mCompositable(aCompositable)
33
0
{
34
0
  MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
35
0
}
36
37
SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage()
38
0
{
39
0
  MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
40
0
}
41
42
size_t
43
SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
44
0
{
45
0
  // NB: Explicitly skipping mTextureClient, the memory is already reported
46
0
  //     at time of allocation in GfxMemoryImageReporter.
47
0
  // Not owned:
48
0
  // - mCompositable
49
0
  return 0;
50
0
}
51
52
TextureClient*
53
SharedPlanarYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder)
54
0
{
55
0
  return mTextureClient.get();
56
0
}
57
58
uint8_t*
59
SharedPlanarYCbCrImage::GetBuffer() const
60
0
{
61
0
  // This should never be used
62
0
  MOZ_ASSERT(false);
63
0
  return nullptr;
64
0
}
65
66
already_AddRefed<gfx::SourceSurface>
67
SharedPlanarYCbCrImage::GetAsSourceSurface()
68
0
{
69
0
  if (!IsValid()) {
70
0
    NS_WARNING("Can't get as surface");
71
0
    return nullptr;
72
0
  }
73
0
  return PlanarYCbCrImage::GetAsSourceSurface();
74
0
}
75
76
bool
77
SharedPlanarYCbCrImage::CopyData(const PlanarYCbCrData& aData)
78
0
{
79
0
  // If mTextureClient has not already been allocated (through Allocate(aData))
80
0
  // allocate it. This code path is slower than the one used when Allocate has
81
0
  // been called since it will trigger a full copy.
82
0
  PlanarYCbCrData data = aData;
83
0
  if (!mTextureClient && !Allocate(data)) {
84
0
    return false;
85
0
  }
86
0
87
0
  TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY);
88
0
  if (!autoLock.Succeeded()) {
89
0
    MOZ_ASSERT(false, "Failed to lock the texture.");
90
0
    return false;
91
0
  }
92
0
93
0
  if (!UpdateYCbCrTextureClient(mTextureClient, aData)) {
94
0
    MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
95
0
    return false;
96
0
  }
97
0
  mTextureClient->MarkImmutable();
98
0
  return true;
99
0
}
100
101
bool
102
SharedPlanarYCbCrImage::AdoptData(const Data& aData)
103
0
{
104
0
  MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
105
0
  if (!mTextureClient) {
106
0
    return false;
107
0
  }
108
0
  mData = aData;
109
0
  mSize = aData.mPicSize;
110
0
  mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
111
0
112
0
  uint8_t *base = GetBuffer();
113
0
  uint32_t yOffset = aData.mYChannel - base;
114
0
  uint32_t cbOffset = aData.mCbChannel - base;
115
0
  uint32_t crOffset = aData.mCrChannel - base;
116
0
117
0
  auto fwd = mCompositable->GetForwarder();
118
0
  bool supportsTextureDirectMapping = fwd->SupportsTextureDirectMapping() &&
119
0
    std::max(aData.mYSize.width,
120
0
             std::max(aData.mYSize.height,
121
0
                      std::max(aData.mCbCrSize.width, aData.mCbCrSize.height))) <= fwd->GetMaxTextureSize();
122
0
  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(
123
0
    gfx::SurfaceFormat::YUV, fwd->GetCompositorBackendType(),
124
0
    supportsTextureDirectMapping);
125
0
126
0
  static_cast<BufferTextureData*>(mTextureClient->GetInternalData())
127
0
    ->SetDesciptor(YCbCrDescriptor(aData.mYSize,
128
0
                                   aData.mYStride,
129
0
                                   aData.mCbCrSize,
130
0
                                   aData.mCbCrStride,
131
0
                                   yOffset,
132
0
                                   cbOffset,
133
0
                                   crOffset,
134
0
                                   aData.mStereoMode,
135
0
                                   aData.mYUVColorSpace,
136
0
                                   aData.mBitDepth,
137
0
                                   hasIntermediateBuffer));
138
0
139
0
  return true;
140
0
}
141
142
bool
143
SharedPlanarYCbCrImage::IsValid() const
144
0
{
145
0
  return mTextureClient && mTextureClient->IsValid();
146
0
}
147
148
bool
149
SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
150
0
{
151
0
  MOZ_ASSERT(!mTextureClient,
152
0
             "This image already has allocated data");
153
0
  static const uint32_t MAX_POOLED_VIDEO_COUNT = 5;
154
0
155
0
  if (!mCompositable->HasTextureClientRecycler()) {
156
0
    // Initialize TextureClientRecycler
157
0
    mCompositable->GetTextureClientRecycler()->SetMaxPoolSize(MAX_POOLED_VIDEO_COUNT);
158
0
  }
159
0
160
0
  {
161
0
    YCbCrTextureClientAllocationHelper helper(aData, mCompositable->GetTextureFlags());
162
0
    mTextureClient = mCompositable->GetTextureClientRecycler()->CreateOrRecycle(helper);
163
0
  }
164
0
165
0
  if (!mTextureClient) {
166
0
    NS_WARNING("SharedPlanarYCbCrImage::Allocate failed.");
167
0
    return false;
168
0
  }
169
0
170
0
  MappedYCbCrTextureData mapped;
171
0
  // The locking here is sort of a lie. The SharedPlanarYCbCrImage just pulls
172
0
  // pointers out of the TextureClient and keeps them around, which works only
173
0
  // because the underlyin BufferTextureData is always mapped in memory even outside
174
0
  // of the lock/unlock interval. That's sad and new code should follow this example.
175
0
  if (!mTextureClient->Lock(OpenMode::OPEN_READ) || !mTextureClient->BorrowMappedYCbCrData(mapped)) {
176
0
    MOZ_CRASH("GFX: Cannot lock or borrow mapped YCbCr");
177
0
  }
178
0
179
0
  aData.mYChannel = mapped.y.data;
180
0
  aData.mCbChannel = mapped.cb.data;
181
0
  aData.mCrChannel = mapped.cr.data;
182
0
183
0
  // copy some of aData's values in mData (most of them)
184
0
  mData.mYChannel = aData.mYChannel;
185
0
  mData.mCbChannel = aData.mCbChannel;
186
0
  mData.mCrChannel = aData.mCrChannel;
187
0
  mData.mYSize = aData.mYSize;
188
0
  mData.mCbCrSize = aData.mCbCrSize;
189
0
  mData.mPicX = aData.mPicX;
190
0
  mData.mPicY = aData.mPicY;
191
0
  mData.mPicSize = aData.mPicSize;
192
0
  mData.mStereoMode = aData.mStereoMode;
193
0
  mData.mYUVColorSpace = aData.mYUVColorSpace;
194
0
  mData.mBitDepth = aData.mBitDepth;
195
0
  // those members are not always equal to aData's, due to potentially different
196
0
  // packing.
197
0
  mData.mYSkip = 0;
198
0
  mData.mCbSkip = 0;
199
0
  mData.mCrSkip = 0;
200
0
  mData.mYStride = aData.mYStride;
201
0
  mData.mCbCrStride = aData.mCbCrStride;
202
0
203
0
  // do not set mBuffer like in PlanarYCbCrImage because the later
204
0
  // will try to manage this memory without knowing it belongs to a
205
0
  // shmem.
206
0
  mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(
207
0
    mData.mYSize, mData.mYStride, mData.mCbCrSize, mData.mCbCrStride);
208
0
  mSize = mData.mPicSize;
209
0
  mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
210
0
211
0
  mTextureClient->Unlock();
212
0
213
0
  return mBufferSize > 0;
214
0
}
215
216
} // namespace layers
217
} // namespace mozilla