1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface_Base.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImagePriv.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDevice.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMallocPixelRef.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkSurface_Raster : public SkSurface_Base { 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSurface_Raster(const SkImageInfo&, void*, size_t rb, 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void (*releaseProc)(void* pixels, void* context), void* context, 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps*); 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSurface_Raster(const SkImageInfo& info, sk_sp<SkPixelRef>, const SkSurfaceProps*); 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* onNewCanvas() override; 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override; 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImage> onNewImageSnapshot() override; 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override; 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onCopyOnWrite(ContentChangeMode) override; 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onRestoreBackingMutability() override; 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap fBitmap; 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t fRowBytes; 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fWeOwnThePixels; 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef SkSurface_Base INHERITED; 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkSurfaceValidateRasterInfo(const SkImageInfo& info, size_t rowBytes) { 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (info.isEmpty()) { 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const size_t kMaxTotalSize = SK_MaxS32; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO(mtklein,brianosman): revisit all these color space decisions 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (info.colorType()) { 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kAlpha_8_SkColorType: 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kGray_8_SkColorType: 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGB_565_SkColorType: 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kARGB_4444_SkColorType: 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGB_888x_SkColorType: 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGBA_1010102_SkColorType: 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGB_101010x_SkColorType: 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (info.colorSpace()) { 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGBA_8888_SkColorType: 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kBGRA_8888_SkColorType: 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (info.colorSpace() && !info.colorSpace()->gammaCloseToSRGB()) { 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRGBA_F16_SkColorType: 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (info.colorSpace() && (!info.colorSpace()->gammaIsLinear())) { 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kIgnoreRowBytesValue == rowBytes) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int shift = SkColorTypeShiftPerPixel(info.colorType()); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint64_t minRB = (uint64_t)info.width() << shift; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (minRB > rowBytes) { 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t alignedRowBytes = rowBytes >> shift << shift; 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (alignedRowBytes != rowBytes) { 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint64_t size = sk_64_mul(info.height(), rowBytes); 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size > kMaxTotalSize) { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb, 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void (*releaseProc)(void* pixels, void* context), void* context, 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps* props) 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(info, props) 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{ 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBitmap.installPixels(info, pixels, rb, releaseProc, context); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRowBytes = 0; // don't need to track the rowbytes 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWeOwnThePixels = false; // We are "Direct" 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, sk_sp<SkPixelRef> pr, 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps* props) 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(pr->width(), pr->height(), props) 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{ 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBitmap.setInfo(info, pr->rowBytes()); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRowBytes = pr->rowBytes(); // we track this, so that subsequent re-allocs will match 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBitmap.setPixelRef(std::move(pr), 0, 0); 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWeOwnThePixels = true; 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkCanvas* SkSurface_Raster::onNewCanvas() { return new SkCanvas(fBitmap, this->props()); } 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkSurface> SkSurface_Raster::onNewSurface(const SkImageInfo& info) { 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkSurface::MakeRaster(info, &this->props()); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint* paint) { 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(fBitmap, x, y, paint); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkImage> SkSurface_Raster::onNewImageSnapshot() { 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCopyPixelsMode cpm = kIfMutable_SkCopyPixelsMode; 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fWeOwnThePixels) { 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // SkImage_raster requires these pixels are immutable for its full lifetime. 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We'll undo this via onRestoreBackingMutability() if we can avoid the COW. 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkPixelRef* pr = fBitmap.pixelRef()) { 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pr->setTemporarilyImmutable(); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cpm = kAlways_SkCopyPixelsMode; 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Our pixels are in memory, so read access on the snapshot SkImage could be cheap. 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Lock the shared pixel ref to ensure peekPixels() is usable. 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkMakeImageFromRasterBitmap(fBitmap, cpm); 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkSurface_Raster::onRestoreBackingMutability() { 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!this->hasCachedImage()); // Shouldn't be any snapshots out there. 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkPixelRef* pr = fBitmap.pixelRef()) { 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pr->restoreMutability(); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // are we sharing pixelrefs with the image? 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImage> cached(this->refCachedImage()); 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(cached); 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBitmapImageGetPixelRef(cached.get()) == fBitmap.pixelRef()) { 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fWeOwnThePixels); 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kDiscard_ContentChangeMode == mode) { 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBitmap.allocPixels(); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap prev(fBitmap); 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBitmap.allocPixels(); 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(prev.info() == fBitmap.info()); 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(prev.rowBytes() == fBitmap.rowBytes()); 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memcpy(fBitmap.getPixels(), prev.getPixels(), fBitmap.computeByteSize()); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBitmap.rowBytes() == fRowBytes); // be sure we always use the same value 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Now fBitmap is a deep copy of itself (and therefore different from 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // what is being used by the image. Next we update the canvas to use 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // this as its backend, so we can't modify the image's pixels anymore. 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->getCachedCanvas()); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkSurface> SkSurface::MakeRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t rb, void (*releaseProc)(void* pixels, void* context), void* context, 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps* props) { 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == releaseProc) { 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot context = nullptr; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkSurfaceValidateRasterInfo(info, rb)) { 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == pixels) { 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_make_sp<SkSurface_Raster>(info, pixels, rb, releaseProc, context, props); 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkSurface> SkSurface::MakeRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes, 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps* props) { 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return MakeRasterDirectReleaseProc(info, pixels, rowBytes, nullptr, nullptr, props); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkSurface> SkSurface::MakeRaster(const SkImageInfo& info, size_t rowBytes, 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceProps* props) { 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkSurfaceValidateRasterInfo(info)) { 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeZeroed(info, rowBytes); 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!pr) { 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (rowBytes) { 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(pr->rowBytes() == rowBytes); 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_make_sp<SkSurface_Raster>(info, std::move(pr), props); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 216