/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
SourceSurfaceSkia::~SourceSurfaceSkia() { // if mIsMapped is true then mChangeMutex will be locked // which will cause problems during destruction.
MOZ_RELEASE_ASSERT(!mIsMapped);
}
// This is only ever called by the DT destructor, which can only ever happen // from one place at a time. Therefore it doesn't need to hold the ChangeMutex // as mSurface is never read to directly and is just there to keep the object // alive, which itself is refcounted in a thread-safe manner. void SourceSurfaceSkia::GiveSurface(SkSurface* aSurface) {
mSurface.reset(aSurface);
mDrawTarget = nullptr;
}
sk_sp<SkImage> SourceSurfaceSkia::GetImage(Maybe<MutexAutoLock>* aLock) { // If we were provided a lock object, we can let the caller access // a shared SkImage and we know it won't go away while the lock is held. // Otherwise we need to call DrawTargetWillChange to ensure we have our // own SkImage. if (aLock) {
MOZ_ASSERT(aLock->isNothing());
aLock->emplace(mChangeMutex);
// Now that we are locked, we can check mDrawTarget. If it's null, then // we're not shared and we can unlock eagerly. if (!mDrawTarget) {
aLock->reset();
}
} else {
DrawTargetWillChange();
}
sk_sp<SkImage> image = mImage; return image;
}
// For the raster image case, we want to use the format and stride // information that the underlying raster image is using, which is // reliable. // For the GPU case (for which peekPixels is false), we can't easily // figure this information out. It is better to report the originally // intended format and stride that we will convert to if this GPU // image is ever read back into a raster image.
SkPixmap pixmap; if (aImage->peekPixels(&pixmap)) {
mFormat =
aFormat != SurfaceFormat::UNKNOWN
? aFormat
: SkiaColorTypeToGfxFormat(pixmap.colorType(), pixmap.alphaType());
mStride = pixmap.rowBytes();
} elseif (aFormat != SurfaceFormat::UNKNOWN) {
mFormat = aFormat;
SkImageInfo info = MakeSkiaImageInfo(mSize, mFormat);
mStride = GetAlignedStride<4>(info.width(), info.bytesPerPixel()); if (!mStride) { returnfalse;
}
} else { returnfalse;
}
mImage = aImage;
if (aOwner) {
mDrawTarget = aOwner;
}
returntrue;
}
already_AddRefed<SourceSurface> SourceSurfaceSkia::ExtractSubrect( const IntRect& aRect) { if (!mImage || aRect.IsEmpty() || !GetRect().Contains(aRect)) { return nullptr;
}
SkImageInfo info = MakeSkiaImageInfo(aRect.Size(), mFormat);
size_t stride = GetAlignedStride<4>(info.width(), info.bytesPerPixel()); if (!stride) { return nullptr;
}
sk_sp<SkImage> subImage = ReadSkImage(mImage, info, stride, aRect.x, aRect.y); if (!subImage) { return nullptr;
}
RefPtr<SourceSurfaceSkia> surface = new SourceSurfaceSkia; if (!surface->InitFromImage(subImage)) { return nullptr;
} return surface.forget().downcast<SourceSurface>();
}
uint8_t* SourceSurfaceSkia::GetData() { if (!mImage) { return nullptr;
}
SkPixmap pixmap; if (!mImage->peekPixels(&pixmap)) {
gfxCriticalError() << "Failed accessing pixels for Skia raster image";
} returnreinterpret_cast<uint8_t*>(pixmap.writable_addr());
}
bool SourceSurfaceSkia::Map(MapType, MappedSurface* aMappedSurface)
MOZ_NO_THREAD_SAFETY_ANALYSIS {
mChangeMutex.Lock();
aMappedSurface->mData = GetData();
aMappedSurface->mStride = Stride();
mIsMapped = !!aMappedSurface->mData; bool isMapped = mIsMapped; if (!mIsMapped) {
mChangeMutex.Unlock();
} // Static analysis will warn due to a conditional Unlock
MOZ_PUSH_IGNORE_THREAD_SAFETY return isMapped;
MOZ_POP_THREAD_SAFETY
}
void SourceSurfaceSkia::DrawTargetWillChange() {
MutexAutoLock lock(mChangeMutex); if (mDrawTarget.exchange(nullptr)) { // Raster snapshots do not use Skia's internal copy-on-write mechanism, // so we need to do an explicit copy here. // GPU snapshots, for which peekPixels is false, will already be dealt // with automatically via the internal copy-on-write mechanism, so we // don't need to do anything for them here.
SkPixmap pixmap; if (mImage->peekPixels(&pixmap)) {
mImage = ReadSkImage(mImage, pixmap.info(), pixmap.rowBytes()); if (!mImage) {
gfxCriticalError() << "Failed copying Skia raster snapshot";
}
}
}
}
} // namespace mozilla::gfx
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.