2016-11-23 14:37:01 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2016 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "GrTextureContext.h"
|
2017-03-30 12:02:11 +00:00
|
|
|
|
|
|
|
#include "GrContextPriv.h"
|
2016-11-23 14:37:01 +00:00
|
|
|
#include "GrDrawingManager.h"
|
|
|
|
#include "GrResourceProvider.h"
|
|
|
|
#include "GrTextureOpList.h"
|
|
|
|
|
|
|
|
#include "../private/GrAuditTrail.h"
|
|
|
|
|
|
|
|
#define ASSERT_SINGLE_OWNER \
|
|
|
|
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
|
2017-01-25 22:31:35 +00:00
|
|
|
#define RETURN_FALSE_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return false; }
|
2016-11-23 14:37:01 +00:00
|
|
|
|
|
|
|
GrTextureContext::GrTextureContext(GrContext* context,
|
|
|
|
GrDrawingManager* drawingMgr,
|
|
|
|
sk_sp<GrTextureProxy> textureProxy,
|
2017-01-18 15:08:39 +00:00
|
|
|
sk_sp<SkColorSpace> colorSpace,
|
2016-11-23 14:37:01 +00:00
|
|
|
GrAuditTrail* auditTrail,
|
|
|
|
GrSingleOwner* singleOwner)
|
2017-01-25 22:31:35 +00:00
|
|
|
: GrSurfaceContext(context, drawingMgr, std::move(colorSpace), auditTrail, singleOwner)
|
2016-11-23 14:37:01 +00:00
|
|
|
, fTextureProxy(std::move(textureProxy))
|
2016-12-15 14:23:05 +00:00
|
|
|
, fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) {
|
2016-11-23 14:37:01 +00:00
|
|
|
SkDEBUGCODE(this->validate();)
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SK_DEBUG
|
|
|
|
void GrTextureContext::validate() const {
|
|
|
|
SkASSERT(fTextureProxy);
|
|
|
|
fTextureProxy->validate(fContext);
|
|
|
|
|
|
|
|
if (fOpList && !fOpList->isClosed()) {
|
|
|
|
SkASSERT(fTextureProxy->getLastOpList() == fOpList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GrTextureContext::~GrTextureContext() {
|
|
|
|
ASSERT_SINGLE_OWNER
|
|
|
|
SkSafeUnref(fOpList);
|
|
|
|
}
|
|
|
|
|
2017-01-30 18:27:37 +00:00
|
|
|
GrRenderTargetProxy* GrTextureContext::asRenderTargetProxy() {
|
|
|
|
// If the proxy can return an RTProxy it should've been wrapped in a RTContext
|
|
|
|
SkASSERT(!fTextureProxy->asRenderTargetProxy());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<GrRenderTargetProxy> GrTextureContext::asRenderTargetProxyRef() {
|
2016-12-14 13:46:47 +00:00
|
|
|
// If the proxy can return an RTProxy it should've been wrapped in a RTContext
|
|
|
|
SkASSERT(!fTextureProxy->asRenderTargetProxy());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-11-23 14:37:01 +00:00
|
|
|
GrTextureOpList* GrTextureContext::getOpList() {
|
|
|
|
ASSERT_SINGLE_OWNER
|
|
|
|
SkDEBUGCODE(this->validate();)
|
|
|
|
|
|
|
|
if (!fOpList || fOpList->isClosed()) {
|
2017-01-25 22:31:35 +00:00
|
|
|
fOpList = this->drawingManager()->newOpList(fTextureProxy.get());
|
2016-11-23 14:37:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return fOpList;
|
|
|
|
}
|
|
|
|
|
2016-12-15 14:23:05 +00:00
|
|
|
// TODO: move this (and GrRenderTargetContext::copy) to GrSurfaceContext?
|
|
|
|
bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
|
|
|
|
const SkIRect& srcRect,
|
|
|
|
const SkIPoint& dstPoint) {
|
2016-11-23 14:37:01 +00:00
|
|
|
ASSERT_SINGLE_OWNER
|
|
|
|
RETURN_FALSE_IF_ABANDONED
|
|
|
|
SkDEBUGCODE(this->validate();)
|
2016-12-15 14:23:05 +00:00
|
|
|
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copy");
|
|
|
|
|
2017-03-30 12:02:11 +00:00
|
|
|
#ifndef ENABLE_MDB
|
|
|
|
// We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
|
|
|
|
// execute the copy immediately. Ensure the data is ready.
|
|
|
|
fContext->contextPriv().flushSurfaceWrites(srcProxy);
|
|
|
|
#endif
|
|
|
|
|
2017-04-06 21:17:15 +00:00
|
|
|
// TODO: defer instantiation until flush time
|
|
|
|
sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider())));
|
|
|
|
if (!src) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
|
|
|
|
sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider())));
|
|
|
|
if (!tex) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-11-23 14:37:01 +00:00
|
|
|
GrTextureOpList* opList = this->getOpList();
|
2017-04-06 21:17:15 +00:00
|
|
|
bool result = opList->copySurface(tex.get(), src.get(), srcRect, dstPoint);
|
2016-11-23 14:37:01 +00:00
|
|
|
|
|
|
|
#ifndef ENABLE_MDB
|
2016-12-07 22:06:19 +00:00
|
|
|
GrOpFlushState flushState(fContext->getGpu(), nullptr);
|
2016-12-07 20:05:04 +00:00
|
|
|
opList->prepareOps(&flushState);
|
|
|
|
opList->executeOps(&flushState);
|
2016-11-23 14:37:01 +00:00
|
|
|
opList->reset();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2017-01-18 15:08:39 +00:00
|
|
|
|
|
|
|
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
|
|
|
|
bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
2017-03-09 21:36:32 +00:00
|
|
|
size_t dstRowBytes, int x, int y, uint32_t flags) {
|
2017-01-18 15:08:39 +00:00
|
|
|
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
|
|
|
|
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
|
|
|
|
if (kUnknown_GrPixelConfig == config) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-09 21:36:32 +00:00
|
|
|
// TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels
|
2017-01-18 15:08:39 +00:00
|
|
|
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
2017-04-06 11:59:41 +00:00
|
|
|
flags |= GrContextPriv::kUnpremul_PixelOpsFlag;
|
2017-01-18 15:08:39 +00:00
|
|
|
}
|
|
|
|
|
2017-04-06 11:59:41 +00:00
|
|
|
return fContext->contextPriv().readSurfacePixels(fTextureProxy.get(), this->getColorSpace(),
|
|
|
|
x, y, dstInfo.width(), dstInfo.height(),
|
|
|
|
config,
|
|
|
|
dstInfo.colorSpace(), dstBuffer, dstRowBytes,
|
|
|
|
flags);
|
2017-01-18 15:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
|
|
|
|
bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
2017-02-22 20:28:38 +00:00
|
|
|
size_t srcRowBytes, int x, int y,
|
|
|
|
uint32_t flags) {
|
2017-01-18 15:08:39 +00:00
|
|
|
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
|
|
|
|
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
|
|
|
|
if (kUnknown_GrPixelConfig == config) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
|
2017-04-06 11:59:41 +00:00
|
|
|
flags |= GrContextPriv::kUnpremul_PixelOpsFlag;
|
2017-01-18 15:08:39 +00:00
|
|
|
}
|
|
|
|
|
2017-04-06 11:59:41 +00:00
|
|
|
return fContext->contextPriv().writeSurfacePixels(fTextureProxy.get(), this->getColorSpace(),
|
|
|
|
x, y, srcInfo.width(), srcInfo.height(),
|
|
|
|
config,
|
|
|
|
srcInfo.colorSpace(), srcBuffer, srcRowBytes,
|
|
|
|
flags);
|
2017-01-18 15:08:39 +00:00
|
|
|
}
|