uint8_t*
SourceSurfaceSkia::GetData()
{
#ifdef USE_SKIA_GPU
  if (mImage->isTextureBacked()) {
    sk_sp<SkImage> raster;
    if (sk_sp<SkData> data = MakeSkData(nullptr, mSize, mStride)) {
      SkImageInfo info = MakeSkiaImageInfo(mSize, mFormat);
      if (mImage->readPixels(info, data->writable_data(), mStride, 0, 0, SkImage::kDisallow_CachingHint)) {
        raster = SkImage::MakeRasterData(info, data, mStride);
      }
    }
    if (raster) {
      mImage = raster;
    } else {
      gfxCriticalError() << "Failed making Skia raster image for GPU surface";
    }
  }
#endif
  SkPixmap pixmap;
  if (!mImage->peekPixels(&pixmap)) {
    gfxCriticalError() << "Failed accessing pixels for Skia raster image";
  }
  return reinterpret_cast<uint8_t*>(pixmap.writable_addr());
}
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;
}
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;
}
bool
SourceSurfaceSkia::InitFromImage(sk_sp<SkImage> aImage,
                                 SurfaceFormat aFormat,
                                 DrawTargetSkia* aOwner)
{
  if (!aImage) {
    return false;
  }

  mSize = IntSize(aImage->width(), aImage->height());

  // 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();
  } else if (aFormat != SurfaceFormat::UNKNOWN) {
    mFormat = aFormat;
    SkImageInfo info = MakeSkiaImageInfo(mSize, mFormat);
    mStride = SkAlign4(info.minRowBytes());
  } else {
    return false;
  }

  mImage = aImage;

  if (aOwner) {
    mDrawTarget = aOwner;
  }

  return true;
}
bool
SourceSurfaceSkia::InitFromData(unsigned char* aData,
                                const IntSize &aSize,
                                int32_t aStride,
                                SurfaceFormat aFormat)
{
  sk_sp<SkData> data = MakeSkData(aData, aSize, aStride);
  if (!data) {
    return false;
  }

  SkImageInfo info = MakeSkiaImageInfo(aSize, aFormat);
  mImage = SkImage::MakeRasterData(info, data, aStride);
  if (!mImage) {
    return false;
  }

  mSize = aSize;
  mFormat = aFormat;
  mStride = aStride;
  return true;
}