Add outline of new GrContext hierarchy

This begins the process of splitting GrContext into:

GrContext_Base, GrImageContext, GrRecordingContext and GrDirectContext.

Change-Id: I3c43045f2a5549b049e95791d65f74d4e16de36f
Reviewed-on: https://skia-review.googlesource.com/c/186878
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Robert Phillips 2019-01-30 13:08:28 -05:00 committed by Skia Commit-Bot
parent 85b856f865
commit 4217ea7ee5
24 changed files with 357 additions and 50 deletions

View File

@ -34,13 +34,16 @@ skia_gpu_sources = [
# Private includes
"$_include/private/GrAuditTrail.h",
"$_include/private/GrColor.h",
"$_include/private/GrContext_Base.h",
"$_include/private/GrCCClipPath.h",
"$_include/private/GrCCPerOpListPaths.h",
"$_include/private/GrImageContext.h",
"$_include/private/GrOpList.h",
"$_include/private/GrProxyRef.h",
"$_include/private/GrSingleOwner.h",
"$_include/private/GrRecordingContext.h",
"$_include/private/GrRenderTargetProxy.h",
"$_include/private/GrResourceKey.h",
"$_include/private/GrSingleOwner.h",
"$_include/private/GrSurfaceProxy.h",
"$_include/private/GrTextureProxy.h",
"$_include/private/GrTypesPriv.h",
@ -54,6 +57,7 @@ skia_gpu_sources = [
"$_src/gpu/GrBackendTextureImageGenerator.h",
"$_src/gpu/GrAHardwareBufferImageGenerator.cpp",
"$_src/gpu/GrAHardwareBufferImageGenerator.h",
"$_src/gpu/GrBaseContextPriv.h",
"$_src/gpu/GrBitmapTextureMaker.cpp",
"$_src/gpu/GrBitmapTextureMaker.h",
"$_src/gpu/GrBlurUtils.cpp",
@ -71,6 +75,7 @@ skia_gpu_sources = [
"$_src/gpu/GrColorSpaceXform.cpp",
"$_src/gpu/GrColorSpaceXform.h",
"$_src/gpu/GrContext.cpp",
"$_src/gpu/GrContext_Base.cpp",
"$_src/gpu/GrContextPriv.h",
"$_src/gpu/GrContextThreadSafeProxy.cpp",
"$_src/gpu/GrContextThreadSafeProxyPriv.h",
@ -105,6 +110,8 @@ skia_gpu_sources = [
"$_src/gpu/GrGpuCommandBuffer.h",
"$_src/gpu/GrGpuResourcePriv.h",
"$_src/gpu/GrGpuResource.cpp",
"$_src/gpu/GrImageContext.cpp",
"$_src/gpu/GrImageContextPriv.h",
"$_src/gpu/GrImageTextureMaker.cpp",
"$_src/gpu/GrImageTextureMaker.h",
"$_src/gpu/GrMemoryPool.cpp",
@ -143,6 +150,8 @@ skia_gpu_sources = [
"$_src/gpu/GrProxyProvider.h",
"$_src/gpu/GrQuad.cpp",
"$_src/gpu/GrQuad.h",
"$_src/gpu/GrRecordingContext.cpp",
"$_src/gpu/GrRecordingContextPriv.h",
"$_src/gpu/GrRect.h",
"$_src/gpu/GrRectanizer.h",
"$_src/gpu/GrRectanizer_pow2.cpp",

View File

@ -12,6 +12,7 @@
#include "SkPathEffect.h"
#include "SkTypes.h"
#include "../private/GrAuditTrail.h"
#include "../private/GrRecordingContext.h"
#include "../private/GrSingleOwner.h"
#include "GrContextOptions.h"
@ -50,7 +51,7 @@ class SkSurfaceProps;
class SkTaskGroup;
class SkTraceMemoryDump;
class SK_API GrContext : public SkRefCnt {
class SK_API GrContext : public GrRecordingContext {
public:
/**
* Creates a GrContext for a backend context. If no GrGLInterface is provided then the result of
@ -266,11 +267,6 @@ public:
GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
GrBackendSemaphore signalSemaphores[]);
/**
* An ID associated with this context, guaranteed to be unique.
*/
uint32_t uniqueID() { return fUniqueID; }
// Provides access to functions that aren't part of the public API.
GrContextPriv contextPriv();
const GrContextPriv contextPriv() const;
@ -291,7 +287,6 @@ protected:
virtual GrAtlasManager* onGetAtlasManager() = 0;
const GrBackendApi fBackend;
sk_sp<const GrCaps> fCaps;
sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
sk_sp<GrSkSLFPFactoryCache> fFPFactoryCache;
@ -324,8 +319,6 @@ private:
// GrRenderTargetContexts. It is also passed to the GrResourceProvider and SkGpuDevice.
mutable GrSingleOwner fSingleOwner;
const uint32_t fUniqueID;
std::unique_ptr<GrDrawingManager> fDrawingManager;
GrAuditTrail fAuditTrail;
@ -354,7 +347,7 @@ private:
*/
static void TextBlobCacheOverBudgetCB(void* data);
typedef SkRefCnt INHERITED;
typedef GrRecordingContext INHERITED;
};
#endif

View File

@ -0,0 +1,58 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrContext_Base_DEFINED
#define GrContext_Base_DEFINED
#include "SkRefCnt.h"
#include "GrTypes.h"
class GrBaseContextPriv;
class GrContext;
class GrImageContext;
class GrRecordingContext;
class SK_API GrContext_Base : public SkRefCnt {
public:
virtual ~GrContext_Base();
/*
* The 3D API backing this context
*/
GrBackendApi backend() const { return fBackend; }
/**
* An identifier for this context. The id is used by all compatible contexts. For example,
* if SkImages are created on one thread using an image creation context, then fed into a
* DDL Recorder on second thread (which has a recording context) and finally replayed on
* a third thread with a direct context, then all three contexts will report the same id.
* It is an error for an image to be used with contexts that report different ids.
*/
uint32_t uniqueID() const { return fUniqueID; }
// Provides access to functions that aren't part of the public API.
GrBaseContextPriv priv();
const GrBaseContextPriv priv() const;
protected:
friend class GrBaseContextPriv; // for hidden functions
GrContext_Base(GrBackendApi backend, uint32_t uniqueID);
GrContext_Base* asBaseContext() { return this; }
virtual GrImageContext* asImageContext() { return nullptr; }
virtual GrRecordingContext* asRecordingContext() { return nullptr; }
virtual GrContext* asDirectContext() { return nullptr; }
private:
const GrBackendApi fBackend;
const uint32_t fUniqueID;
typedef SkRefCnt INHERITED;
};
#endif

View File

@ -0,0 +1,34 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrImageContext_DEFINED
#define GrImageContext_DEFINED
#include "GrContext_Base.h"
class GrImageContextPriv;
class SK_API GrImageContext : public GrContext_Base {
public:
~GrImageContext() override;
// Provides access to functions that aren't part of the public API.
GrImageContextPriv priv();
const GrImageContextPriv priv() const;
protected:
friend class GrImageContextPriv; // for hidden functions
GrImageContext(GrBackendApi backend, uint32_t uniqueID);
GrImageContext* asImageContext() override { return this; }
private:
typedef GrContext_Base INHERITED;
};
#endif

View File

@ -0,0 +1,34 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrRecordingContext_DEFINED
#define GrRecordingContext_DEFINED
#include "GrImageContext.h"
class GrRecordingContextPriv;
class SK_API GrRecordingContext : public GrImageContext {
public:
~GrRecordingContext() override;
// Provides access to functions that aren't part of the public API.
GrRecordingContextPriv priv();
const GrRecordingContextPriv priv() const;
protected:
friend class GrRecordingContextPriv; // for hidden functions
GrRecordingContext(GrBackendApi backend, uint32_t uniqueID);
GrRecordingContext* asRecordingContext() override { return this; }
private:
typedef GrImageContext INHERITED;
};
#endif

View File

@ -324,7 +324,7 @@ void CCPRGeometryView::DrawCoverageCountOp::onExecute(GrOpFlushState* state,
const SkRect& chainBounds) {
GrResourceProvider* rp = state->resourceProvider();
GrContext* context = state->gpu()->getContext();
GrGLGpu* glGpu = GrBackendApi::kOpenGL == context->contextPriv().getBackend()
GrGLGpu* glGpu = GrBackendApi::kOpenGL == context->backend()
? static_cast<GrGLGpu*>(state->gpu())
: nullptr;
if (glGpu) {

View File

@ -109,7 +109,7 @@ bool SkDeferredDisplayListRecorder::init() {
bool usesGLFBO0 = fCharacterization.usesGLFBO0();
if (usesGLFBO0) {
if (GrBackendApi::kOpenGL != fContext->contextPriv().getBackend() ||
if (GrBackendApi::kOpenGL != fContext->backend() ||
fCharacterization.isTextureable()) {
return false;
}

View File

@ -57,7 +57,7 @@ static bool can_import_protected_content_eglimpl() {
}
static bool can_import_protected_content(GrContext* context) {
if (GrBackendApi::kOpenGL == context->contextPriv().getBackend()) {
if (GrBackendApi::kOpenGL == context->backend()) {
// Only compute whether the extension is present once the first time this
// function is called.
static bool hasIt = can_import_protected_content_eglimpl();
@ -158,7 +158,7 @@ static GrBackendTexture make_vk_backend_texture(
GrAHardwareBufferImageGenerator::DeleteImageCtx* deleteCtx,
bool isProtectedContent,
const GrBackendFormat& backendFormat) {
SkASSERT(context->contextPriv().getBackend() == GrBackendApi::kVulkan);
SkASSERT(context->backend() == GrBackendApi::kVulkan);
GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu());
VkPhysicalDevice physicalDevice = gpu->physicalDevice();
@ -434,11 +434,11 @@ static GrBackendTexture make_backend_texture(
}
bool createProtectedImage = isProtectedContent && can_import_protected_content(context);
if (GrBackendApi::kOpenGL == context->contextPriv().getBackend()) {
if (GrBackendApi::kOpenGL == context->backend()) {
return make_gl_backend_texture(context, hardwareBuffer, width, height, config, deleteProc,
deleteCtx, createProtectedImage, backendFormat);
} else {
SkASSERT(GrBackendApi::kVulkan == context->contextPriv().getBackend());
SkASSERT(GrBackendApi::kVulkan == context->backend());
#ifdef SK_VULKAN
// Currently we don't support protected images on vulkan
SkASSERT(!createProtectedImage);
@ -542,7 +542,7 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
}
GrBackendFormat backendFormat = get_backend_format(context, fHardwareBuffer,
context->contextPriv().getBackend(),
context->backend(),
fBufferFormat);
GrPixelConfig pixelConfig = context->contextPriv().caps()->getConfigFromBackendFormat(
backendFormat, this->getInfo().colorType());
@ -560,9 +560,9 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
desc.fConfig = pixelConfig;
GrTextureType textureType = GrTextureType::k2D;
if (context->contextPriv().getBackend() == GrBackendApi::kOpenGL) {
if (context->backend() == GrBackendApi::kOpenGL) {
textureType = GrTextureType::kExternal;
} else if (context->contextPriv().getBackend() == GrBackendApi::kVulkan) {
} else if (context->backend() == GrBackendApi::kVulkan) {
const VkFormat* format = backendFormat.getVkFormat();
SkASSERT(format);
if (*format == VK_FORMAT_UNDEFINED) {
@ -653,8 +653,8 @@ bool GrAHardwareBufferImageGenerator::onIsValid(GrContext* context) const {
if (nullptr == context) {
return false; //CPU backend is not supported, because hardware buffer can be swizzled
}
return GrBackendApi::kOpenGL == context->contextPriv().getBackend() ||
GrBackendApi::kVulkan == context->contextPriv().getBackend();
return GrBackendApi::kOpenGL == context->backend() ||
GrBackendApi::kVulkan == context->backend();
}
#endif //SK_BUILD_FOR_ANDROID_FRAMEWORK

View File

@ -92,7 +92,7 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
GrContext* context, const SkImageInfo& info, const SkIPoint& origin, bool willNeedMipMaps) {
SkASSERT(context);
if (context->contextPriv().getBackend() != fBackendTexture.backend()) {
if (context->backend() != fBackendTexture.backend()) {
return nullptr;
}
if (info.colorType() != this->getInfo().colorType()) {

View File

@ -0,0 +1,40 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrBaseContextPriv_DEFINED
#define GrBaseContextPriv_DEFINED
#include "GrContext_Base.h"
/** Class that exposes methods on GrContext_Base that are only intended for use internal to Skia.
This class is purely a privileged window into GrContext_Base. It should never have
additional data members or virtual methods. */
class GrBaseContextPriv {
public:
// from GrContext_Base
private:
explicit GrBaseContextPriv(GrContext_Base* context) : fContext(context) {}
GrBaseContextPriv(const GrBaseContextPriv&); // unimpl
GrBaseContextPriv& operator=(const GrBaseContextPriv&); // unimpl
// No taking addresses of this type.
const GrBaseContextPriv* operator&() const;
GrBaseContextPriv* operator&();
GrContext_Base* fContext;
friend class GrContext_Base; // to construct/copy this type.
};
inline GrBaseContextPriv GrContext_Base::priv() { return GrBaseContextPriv(this); }
inline const GrBaseContextPriv GrContext_Base::priv () const {
return GrBaseContextPriv(const_cast<GrContext_Base*>(this));
}
#endif

View File

@ -59,18 +59,8 @@
////////////////////////////////////////////////////////////////////////////////
static int32_t next_id() {
static std::atomic<int32_t> nextID{1};
int32_t id;
do {
id = nextID++;
} while (id == SK_InvalidGenID);
return id;
}
GrContext::GrContext(GrBackendApi backend, int32_t id)
: fBackend(backend)
, fUniqueID(SK_InvalidGenID == id ? next_id() : id) {
: INHERITED(backend, id) {
fResourceCache = nullptr;
fResourceProvider = nullptr;
fProxyProvider = nullptr;
@ -84,7 +74,7 @@ bool GrContext::initCommon(const GrContextOptions& options) {
if (fGpu) {
fCaps = fGpu->refCaps();
fResourceCache = new GrResourceCache(fCaps.get(), &fSingleOwner, fUniqueID);
fResourceCache = new GrResourceCache(fCaps.get(), &fSingleOwner, this->uniqueID());
fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner,
options.fExplicitlyAllocateGPUResources);
fProxyProvider =
@ -167,6 +157,10 @@ GrContext::~GrContext() {
delete fGlyphCache;
}
sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
return fThreadSafeProxy;
}
//////////////////////////////////////////////////////////////////////////////
void GrContext::abandonContext() {
@ -1153,7 +1147,7 @@ SkString GrContextPriv::dump() const {
GR_STATIC_ASSERT(1 == (unsigned)GrBackendApi::kOpenGL);
GR_STATIC_ASSERT(2 == (unsigned)GrBackendApi::kVulkan);
GR_STATIC_ASSERT(3 == (unsigned)GrBackendApi::kMock);
writer.appendString("backend", kBackendStr[(unsigned)fContext->fBackend]);
writer.appendString("backend", kBackendStr[(unsigned)fContext->backend()]);
writer.appendName("caps");
fContext->fCaps->dumpJSON(&writer);

View File

@ -28,6 +28,13 @@ class SkDeferredDisplayList;
data members or virtual methods. */
class GrContextPriv {
public:
// from GrContext_Base
// from GrImageContext
// from GrRecordingContext
/**
* Create a GrContext without a resource cache
*/
@ -182,8 +189,6 @@ public:
GrColorType srcColorType, SkColorSpace* srcColorSpace,
const void* buffer, size_t rowBytes, uint32_t pixelOpsFlags = 0);
GrBackendApi getBackend() const { return fContext->fBackend; }
SkTaskGroup* getTaskGroup() { return fContext->fTaskGroup.get(); }
GrProxyProvider* proxyProvider() { return fContext->fProxyProvider; }

View File

@ -26,10 +26,6 @@ GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uin
GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
return fThreadSafeProxy;
}
bool GrContextThreadSafeProxy::matches(GrContext* context) const {
return context->uniqueID() == fContextUniqueID;
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrContext_Base.h"
static int32_t next_id() {
static std::atomic<int32_t> nextID{1};
int32_t id;
do {
id = nextID++;
} while (id == SK_InvalidGenID);
return id;
}
GrContext_Base::GrContext_Base(GrBackendApi backend,
uint32_t uniqueID)
: fBackend(backend)
, fUniqueID(SK_InvalidGenID == uniqueID ? next_id() : uniqueID) {
}
GrContext_Base::~GrContext_Base() {
}

View File

@ -64,7 +64,8 @@ protected:
SkASSERT(!fFPFactoryCache);
fFPFactoryCache.reset(new GrSkSLFPFactoryCache());
fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(),
fBackend, options, fFPFactoryCache));
this->backend(),
options, fFPFactoryCache));
if (!INHERITED::initCommon(options)) {
return false;

View File

@ -0,0 +1,14 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrImageContext.h"
GrImageContext::GrImageContext(GrBackendApi backend, uint32_t uniqueID)
: INHERITED(backend, uniqueID) {
}
GrImageContext::~GrImageContext() {}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrImageContextPriv_DEFINED
#define GrImageContextPriv_DEFINED
#include "GrImageContext.h"
/** Class that exposes methods on GrImageContext that are only intended for use internal to Skia.
This class is purely a privileged window into GrImageContext. It should never have
additional data members or virtual methods. */
class GrImageContextPriv {
public:
// from GrContext_Base
// from GrImageContext
private:
explicit GrImageContextPriv(GrImageContext* context) : fContext(context) {}
GrImageContextPriv(const GrImageContextPriv&); // unimpl
GrImageContextPriv& operator=(const GrImageContextPriv&); // unimpl
// No taking addresses of this type.
const GrImageContextPriv* operator&() const;
GrImageContextPriv* operator&();
GrImageContext* fContext;
friend class GrImageContext; // to construct/copy this type.
};
inline GrImageContextPriv GrImageContext::priv() { return GrImageContextPriv(this); }
inline const GrImageContextPriv GrImageContext::priv () const {
return GrImageContextPriv(const_cast<GrImageContext*>(this));
}
#endif

View File

@ -0,0 +1,15 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrRecordingContext.h"
GrRecordingContext::GrRecordingContext(GrBackendApi backend, uint32_t uniqueID)
: INHERITED(backend, uniqueID) {
}
GrRecordingContext::~GrRecordingContext() { }

View File

@ -0,0 +1,44 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrRecordingContextPriv_DEFINED
#define GrRecordingContextPriv_DEFINED
#include "GrRecordingContext.h"
/** Class that exposes methods to GrRecordingContext that are only intended for use internal to
Skia. This class is purely a privileged window into GrRecordingContext. It should never have
additional data members or virtual methods. */
class GrRecordingContextPriv {
public:
// from GrContext_Base
// from GrImageContext
// from GrRecordingContext
private:
explicit GrRecordingContextPriv(GrRecordingContext* context) : fContext(context) {}
GrRecordingContextPriv(const GrRecordingContextPriv&); // unimpl
GrRecordingContextPriv& operator=(const GrRecordingContextPriv&); // unimpl
// No taking addresses of this type.
const GrRecordingContextPriv* operator&() const;
GrRecordingContextPriv* operator&();
GrRecordingContext* fContext;
friend class GrRecordingContext; // to construct/copy this type.
};
inline GrRecordingContextPriv GrRecordingContext::priv() { return GrRecordingContextPriv(this); }
inline const GrRecordingContextPriv GrRecordingContext::priv () const {
return GrRecordingContextPriv(const_cast<GrRecordingContext*>(this));
}
#endif

View File

@ -1757,7 +1757,7 @@ void SkGpuDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList) {
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix, SkCanvas* canvas) {
GrBackendApi api = this->context()->contextPriv().getBackend();
GrBackendApi api = this->context()->backend();
if (GrBackendApi::kVulkan == api) {
const SkMatrix& ctm = canvas->getTotalMatrix();
const SkMatrix& combinedMatrix = matrix ? SkMatrix::Concat(ctm, *matrix) : ctm;

View File

@ -23,7 +23,7 @@ sk_sp<GrVkSecondaryCBDrawContext> GrVkSecondaryCBDrawContext::Make(GrContext* ct
return nullptr;
}
if (ctx->contextPriv().getBackend() != GrBackendApi::kVulkan) {
if (ctx->backend() != GrBackendApi::kVulkan) {
return nullptr;
}

View File

@ -53,7 +53,7 @@ static GrBackendFormat create_backend_format(GrContext* context,
GrPixelConfig config) {
const GrCaps* caps = context->contextPriv().caps();
switch (context->contextPriv().getBackend()) {
switch (context->backend()) {
case GrBackendApi::kOpenGL: {
const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(caps);
GrGLStandard standard = glCaps->standard();

View File

@ -173,7 +173,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTest, reporter, ctxInfo) {
expectedDoneCnt,
reporter));
bool isVulkan = GrBackendApi::kVulkan == ctx->contextPriv().getBackend();
bool isVulkan = GrBackendApi::kVulkan == ctx->backend();
canvas->flush();
expectedFulfillCnt++;
expectedReleaseCnt++;
@ -328,7 +328,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTextureReuse, reporter, ctxInfo)
expectedDoneCnt,
reporter));
bool isVulkan = GrBackendApi::kVulkan == ctx->contextPriv().getBackend();
bool isVulkan = GrBackendApi::kVulkan == ctx->backend();
canvas->flush();
expectedFulfillCnt++;
expectedReleaseCnt++;

View File

@ -70,7 +70,7 @@ void basic_transfer_test(skiatest::Reporter* reporter, GrContext* context, GrCol
const int kTextureHeight = 16;
#ifdef SK_BUILD_FOR_IOS
// UNPACK_ROW_LENGTH is broken on iOS so rowBytes needs to match data width
const int kBufferWidth = GrBackendApi::kOpenGL == context->contextPriv().getBackend() ? 16 : 20;
const int kBufferWidth = GrBackendApi::kOpenGL == context->backend() ? 16 : 20;
#else
const int kBufferWidth = 20;
#endif
@ -144,7 +144,7 @@ void basic_transfer_test(skiatest::Reporter* reporter, GrContext* context, GrCol
// transfer partial data
#ifdef SK_BUILD_FOR_IOS
// UNPACK_ROW_LENGTH is broken on iOS so we can't do partial transfers
if (GrBackendApi::kOpenGL == context->contextPriv().getBackend()) {
if (GrBackendApi::kOpenGL == context->backend()) {
continue;
}
#endif