Add API for creating SkImage from AHB while uploading data to it.

Bug: skia:
Change-Id: I893b511450df7f15bdde202fe01ce223ea2294a9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/195366
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Greg Daniel 2019-03-04 13:08:25 -05:00 committed by Skia Commit-Bot
parent ad39760239
commit b6c15babd5
5 changed files with 122 additions and 3 deletions

View File

@ -566,6 +566,22 @@ public:
SkAlphaType alphaType = kPremul_SkAlphaType,
sk_sp<SkColorSpace> colorSpace = nullptr,
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
/** Creates SkImage from Android hardware buffer and uploads the data from the SkPixmap to it.
Returned SkImage takes a reference on the buffer.
Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
@param pixmap SkPixmap that contains data to be uploaded to the AHardwareBuffer
@param hardwareBuffer AHardwareBuffer Android hardware buffer
@param surfaceOrigin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
@return created SkImage, or nullptr
*/
static sk_sp<SkImage> MakeFromAHardwareBufferWithData(
GrContext* context,
const SkPixmap& pixmap,
AHardwareBuffer* hardwareBuffer,
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
#endif
/** Returns pixel count in each row.

View File

@ -185,6 +185,16 @@ public:
*/
SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
/** Returns smart pointer to SkColorSpace, the range of colors, associated with
SkImageInfo. The smart pointer tracks the number of objects sharing this
SkColorSpace reference so the memory is released when the owners destruct.
The returned SkColorSpace is immutable.
@return SkColorSpace in SkImageInfo wrapped in a smart pointer
*/
sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); }
/** Returns true if SkAlphaType is kOpaque_SkAlphaType.
Does not check if SkColorType allows alpha, or if any pixel value has
transparency.

View File

@ -160,6 +160,7 @@ private:
friend class GrContextPriv; // access to: flush
friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class
friend class GrRecordingContext; // access to: ctor
friend class SkImage; // for access to: flush
static const int kNumPixelGeometries = 5; // The different pixel geometries
static const int kNumDFTOptions = 2; // DFT or no DFT

View File

@ -10,6 +10,7 @@
#include <type_traits>
#include "GrAHardwareBufferImageGenerator.h"
#include "GrAHardwareBufferUtils.h"
#include "GrBackendSurface.h"
#include "GrBackendTextureImageGenerator.h"
#include "GrBitmapTextureMaker.h"
@ -18,6 +19,7 @@
#include "GrColorSpaceXform.h"
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrDrawingManager.h"
#include "GrGpu.h"
#include "GrImageTextureMaker.h"
#include "GrProxyProvider.h"
@ -28,6 +30,7 @@
#include "GrSurfacePriv.h"
#include "GrTexture.h"
#include "GrTextureAdjuster.h"
#include "GrTextureContext.h"
#include "GrTexturePriv.h"
#include "GrTextureProxy.h"
#include "GrTextureProxyPriv.h"
@ -581,6 +584,89 @@ sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer,
auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin);
return SkImage::MakeFromGenerator(std::move(gen));
}
sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrContext* context,
const SkPixmap& pixmap,
AHardwareBuffer* hardwareBuffer,
GrSurfaceOrigin surfaceOrigin) {
AHardwareBuffer_Desc bufferDesc;
AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);
if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) {
return nullptr;
}
GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(context,
hardwareBuffer,
bufferDesc.format,
true);
if (!backendFormat.isValid()) {
return nullptr;
}
GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
GrAHardwareBufferUtils::DeleteImageCtx deleteImageCtx = nullptr;
GrBackendTexture backendTexture =
GrAHardwareBufferUtils::MakeBackendTexture(context, hardwareBuffer,
bufferDesc.width, bufferDesc.height,
&deleteImageProc, &deleteImageCtx,
false, backendFormat, true);
if (!backendTexture.isValid()) {
return nullptr;
}
SkASSERT(deleteImageProc);
SkColorType colorType =
GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
backendTexture.fConfig = context->priv().caps()->getConfigFromBackendFormat(backendFormat,
colorType);
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
if (!proxyProvider) {
deleteImageProc(deleteImageCtx);
return nullptr;
}
sk_sp<GrTextureProxy> proxy =
proxyProvider->wrapBackendTexture(backendTexture, surfaceOrigin,
kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
kRW_GrIOType, deleteImageProc, deleteImageCtx);
if (!proxy) {
deleteImageProc(deleteImageCtx);
return nullptr;
}
sk_sp<SkColorSpace> cs = pixmap.refColorSpace();
SkAlphaType at = pixmap.alphaType();
sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, at,
proxy, cs);
if (!image) {
return nullptr;
}
GrDrawingManager* drawingManager = context->priv().drawingManager();
if (!drawingManager) {
return nullptr;
}
sk_sp<GrTextureContext> texContext = drawingManager->makeTextureContext(proxy, cs);
if (!texContext) {
return nullptr;
}
SkImageInfo srcInfo = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType, at,
std::move(cs));
texContext->writePixels(srcInfo, pixmap.addr(0, 0), pixmap.rowBytes(), 0, 0);
drawingManager->flush(proxy.get(), SkSurface::BackendSurfaceAccess::kNoAccess,
SkSurface::kSyncCpu_FlushFlag, 0, nullptr);
return image;
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -624,9 +624,15 @@ sk_sp<SkSurface> SkSurface::MakeFromAHardwareBuffer(GrContext* context,
SkColorType colorType =
GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
return SkSurface::MakeFromBackendTexture(context, backendTexture, origin, 0,
colorType, std::move(colorSpace),
surfaceProps, deleteImageProc, deleteImageCtx);
sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, backendTexture,
origin, 0, colorType, std::move(colorSpace), surfaceProps, deleteImageProc,
deleteImageCtx);
if (!surface) {
SkASSERT(deleteImageProc);
deleteImageProc(deleteImageCtx);
}
return surface;
} else {
return nullptr;
}