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:
parent
ad39760239
commit
b6c15babd5
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user