gecko/gfx/2d/SourceSurfaceSkia.cpp

146 lines
3.0 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#include "Logging.h"
#include "SourceSurfaceSkia.h"
#include "skia/include/core/SkBitmap.h"
#include "skia/include/core/SkDevice.h"
#include "HelpersSkia.h"
#include "DrawTargetSkia.h"
#include "DataSurfaceHelpers.h"
#ifdef USE_SKIA_GPU
#include "skia/include/gpu/SkGrPixelRef.h"
#endif
namespace mozilla {
namespace gfx {
SourceSurfaceSkia::SourceSurfaceSkia()
: mDrawTarget(nullptr), mLocked(false)
{
}
SourceSurfaceSkia::~SourceSurfaceSkia()
{
MaybeUnlock();
if (mDrawTarget) {
mDrawTarget->SnapshotDestroyed();
mDrawTarget = nullptr;
}
}
IntSize
SourceSurfaceSkia::GetSize() const
{
return mSize;
}
SurfaceFormat
SourceSurfaceSkia::GetFormat() const
{
return mFormat;
}
bool
SourceSurfaceSkia::InitFromCanvas(SkCanvas* aCanvas,
SurfaceFormat aFormat,
DrawTargetSkia* aOwner)
{
mBitmap = aCanvas->getDevice()->accessBitmap(false);
mFormat = aFormat;
mSize = IntSize(mBitmap.width(), mBitmap.height());
mStride = mBitmap.rowBytes();
mDrawTarget = aOwner;
return true;
}
bool
SourceSurfaceSkia::InitFromData(unsigned char* aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat)
{
SkBitmap temp;
temp.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride);
temp.setPixels(aData);
if (!temp.copyTo(&mBitmap)) {
return false;
}
mSize = aSize;
mFormat = aFormat;
mStride = mBitmap.rowBytes();
return true;
}
#ifdef USE_SKIA_GPU
bool
SourceSurfaceSkia::InitFromGrTexture(GrTexture* aTexture,
const IntSize &aSize,
SurfaceFormat aFormat)
{
if (!aTexture) {
return false;
}
// Create a GPU pixelref wrapping the texture.
SkImageInfo imgInfo = MakeSkiaImageInfo(aSize, aFormat);
mBitmap.setInfo(imgInfo);
mBitmap.setPixelRef(new SkGrPixelRef(imgInfo, aTexture))->unref();
mSize = aSize;
mFormat = aFormat;
mStride = mBitmap.rowBytes();
return true;
}
#endif
unsigned char*
SourceSurfaceSkia::GetData()
{
if (!mLocked) {
mBitmap.lockPixels();
mLocked = true;
}
unsigned char *pixels = (unsigned char *)mBitmap.getPixels();
return pixels;
}
void
SourceSurfaceSkia::DrawTargetWillChange()
{
if (mDrawTarget) {
MaybeUnlock();
mDrawTarget = nullptr;
// First try a deep copy to avoid a readback from the GPU.
// If that fails, try the CPU copy.
if (!mBitmap.deepCopyTo(&mBitmap) ||
!mBitmap.copyTo(&mBitmap)) {
mBitmap.reset();
}
}
}
void
SourceSurfaceSkia::MaybeUnlock()
{
if (mLocked) {
mBitmap.unlockPixels();
mLocked = false;
}
}
} // namespace gfx
} // namespace mozilla