Add mock config to tools and run through gms and benchs without crashing.

Change-Id: I7e2474129ef2b15899ad2baeb8d18f39d05da98c
Reviewed-on: https://skia-review.googlesource.com/21820
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2017-07-07 12:56:11 -04:00 committed by Skia Commit-Bot
parent a531f25028
commit 8fe24272fa
15 changed files with 225 additions and 58 deletions

View File

@ -37,8 +37,8 @@ protected:
return;
}
auto srgb = SkColorSpace::MakeSRGB();
SkImageInfo info = SkImageInfo::Make(fW, fH, kN32_SkColorType, kPremul_SkAlphaType,
srgb);
SkImageInfo info =
SkImageInfo::Make(fW, fH, kRGBA_8888_SkColorType, kPremul_SkAlphaType, srgb);
fSurface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
}

View File

@ -10,6 +10,7 @@
#include "GrTypes.h"
#include "gl/GrGLTypes.h"
#include "mock/GrMockTypes.h"
#ifdef SK_VULKAN
#include "vk/GrVkTypes.h"
@ -17,6 +18,9 @@
class SK_API GrBackendTexture {
public:
// Creates an invalid backend texture.
GrBackendTexture() : fConfig(kUnknown_GrPixelConfig) {}
GrBackendTexture(int width,
int height,
GrPixelConfig config,
@ -28,6 +32,11 @@ public:
const GrVkImageInfo& vkInfo);
#endif
GrBackendTexture(int width,
int height,
GrPixelConfig config,
const GrMockTextureInfo& mockInfo);
int width() const { return fWidth; }
int height() const { return fHeight; }
GrPixelConfig config() const { return fConfig; }
@ -43,7 +52,13 @@ public:
const GrVkImageInfo* getVkImageInfo() const;
#endif
// If the backend API is Mock, this returns a pointer to the GrMockTextureInfo struct. Otherwise
// it returns nullptr.
const GrMockTextureInfo* getMockTextureInfo() const;
private:
bool isValid() const { return fConfig != kUnknown_GrPixelConfig; }
// Temporary constructor which can be used to convert from a GrBackendTextureDesc.
GrBackendTexture(const GrBackendTextureDesc& desc, GrBackend backend);
@ -61,6 +76,7 @@ private:
#ifdef SK_VULKAN
GrVkImageInfo fVkInfo;
#endif
GrMockTextureInfo fMockInfo;
};
};

View File

@ -188,11 +188,12 @@ enum GrBackend {
kMetal_GrBackend,
kOpenGL_GrBackend,
kVulkan_GrBackend,
/**
* Mock is a backend that does not draw anything. It is used for unit tests
* and to measure CPU overhead.
*/
kMock_GrBackend,
kLast_GrBackend = kVulkan_GrBackend
};
const int kBackendCount = kLast_GrBackend + 1;
/**
* Backend-specific 3D context handle

View File

@ -10,6 +10,10 @@
#include "GrTypes.h"
struct GrMockTextureInfo {
int fID;
};
/**
* A pointer to this type is used as the GrBackendContext when creating a Mock GrContext. It can be
* used to specificy capability options for the mock context. If nullptr is used a default
@ -17,10 +21,11 @@
*/
struct GrMockOptions {
GrMockOptions() {
// By default RGBA_8888 is textureable and renderable and A8 is texturable.
// By default RGBA_8888 is textureable and renderable and A8 and RGB565 are texturable.
fConfigOptions[kRGBA_8888_GrPixelConfig].fRenderable[0] = true;
fConfigOptions[kRGBA_8888_GrPixelConfig].fTexturable = true;
fConfigOptions[kAlpha_8_GrPixelConfig].fTexturable = true;
fConfigOptions[kRGB_565_GrPixelConfig].fTexturable = true;
}
struct ConfigOptions {

View File

@ -279,7 +279,7 @@ private:
SkTHashTable<Pair, K> fTable;
};
// A set of T. T is treated as an ordiary copyable C++ type.
// A set of T. T is treated as an ordinary copyable C++ type.
template <typename T, typename HashT = SkGoodHash>
class SkTHashSet : SkNoncopyable {
public:

View File

@ -74,6 +74,10 @@ sk_sp<GrTextureProxy> SkColorSpaceXformImageGenerator::onGenerateTexture(GrConte
sk_sp<GrTextureProxy> proxy = GrUploadBitmapToTextureProxy(ctx->resourceProvider(),
fSrc, nullptr);
if (!proxy) {
return nullptr;
}
sk_sp<SkColorSpace> srcSpace =
fSrc.colorSpace() ? sk_ref_sp(fSrc.colorSpace()) : SkColorSpace::MakeSRGB();
auto xform = GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), fDst.get());

View File

@ -33,29 +33,46 @@ GrBackendTexture::GrBackendTexture(int width,
, fBackend(kOpenGL_GrBackend)
, fGLInfo(glInfo) {}
GrBackendTexture::GrBackendTexture(int width,
int height,
GrPixelConfig config,
const GrMockTextureInfo& mockInfo)
: fWidth(width)
, fHeight(height)
, fConfig(config)
, fBackend(kMock_GrBackend)
, fMockInfo(mockInfo) {}
GrBackendTexture::GrBackendTexture(const GrBackendTextureDesc& desc, GrBackend backend)
: fWidth(desc.fWidth)
, fHeight(desc.fHeight)
, fConfig(desc.fConfig)
, fBackend(backend) {
if (kOpenGL_GrBackend == backend) {
fGLInfo = *reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
} else {
SkASSERT(kVulkan_GrBackend == backend);
switch (backend) {
case kOpenGL_GrBackend:
fGLInfo = *reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
break;
#ifdef SK_VULKAN
const GrVkImageInfo* vkInfo =
reinterpret_cast<const GrVkImageInfo*>(desc.fTextureHandle);
fConfig = GrVkFormatToPixelConfig(vkInfo->fFormat);
fVkInfo = *vkInfo;
#else
fConfig = kUnknown_GrPixelConfig;
case kVulkan_GrBackend: {
const GrVkImageInfo* vkInfo =
reinterpret_cast<const GrVkImageInfo*>(desc.fTextureHandle);
fConfig = GrVkFormatToPixelConfig(vkInfo->fFormat);
fVkInfo = *vkInfo;
break;
}
#endif
case kMock_GrBackend:
fMockInfo = *reinterpret_cast<const GrMockTextureInfo*>(desc.fTextureHandle);
break;
default:
fConfig = kUnknown_GrPixelConfig;
break;
}
}
#ifdef SK_VULKAN
const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const {
if (kVulkan_GrBackend == fBackend) {
if (this->isValid() && kVulkan_GrBackend == fBackend) {
return &fVkInfo;
}
return nullptr;
@ -63,12 +80,19 @@ const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const {
#endif
const GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() const {
if (kOpenGL_GrBackend == fBackend) {
if (this->isValid() && kOpenGL_GrBackend == fBackend) {
return &fGLInfo;
}
return nullptr;
}
const GrMockTextureInfo* GrBackendTexture::getMockTextureInfo() const {
if (this->isValid() && kMock_GrBackend == fBackend) {
return &fMockInfo;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef SK_VULKAN

View File

@ -33,15 +33,24 @@ static GrBackendTexture make_backend_texture_from_handle(GrBackend backend,
int width, int height,
GrPixelConfig config,
GrBackendObject handle) {
switch (backend) {
case kOpenGL_GrBackend: {
const GrGLTextureInfo* glInfo = (const GrGLTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *glInfo);
}
#ifdef SK_VULKAN
if (kVulkan_GrBackend == backend) {
GrVkImageInfo* vkInfo = (GrVkImageInfo*)(handle);
return GrBackendTexture(width, height, *vkInfo);
}
case kVulkan_GrBackend: {
const GrVkImageInfo* vkInfo = (const GrVkImageInfo*)(handle);
return GrBackendTexture(width, height, *vkInfo);
}
#endif
SkASSERT(kOpenGL_GrBackend == backend);
GrGLTextureInfo* glInfo = (GrGLTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *glInfo);
case kMock_GrBackend: {
const GrMockTextureInfo* mockInfo = (const GrMockTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *mockInfo);
}
default:
return GrBackendTexture();
}
}
std::unique_ptr<SkImageGenerator>

View File

@ -9,7 +9,7 @@
#define GrMockCaps_DEFINED
#include "GrCaps.h"
#include "mock/GrMockOptions.h"
#include "mock/GrMockTypes.h"
class GrMockCaps : public GrCaps {
public:
@ -20,6 +20,7 @@ public:
fMaxRenderTargetSize = SkTMin(options.fMaxRenderTargetSize, fMaxTextureSize);
fMaxVertexAttributes = options.fMaxVertexAttributes;
fShaderCaps.reset(new GrShaderCaps(contextOptions));
this->applyOptionsOverrides(contextOptions);
}
bool isConfigTexturable(GrPixelConfig config) const override {
return fOptions.fConfigOptions[config].fTexturable;

View File

@ -12,6 +12,18 @@
#include "GrMockStencilAttachment.h"
#include "GrMockTexture.h"
int GrMockGpu::NextInternalTextureID() {
static int gID = 0;
return sk_atomic_inc(&gID) + 1;
}
int GrMockGpu::NextExternalTextureID() {
// We use negative ints for the "testing only external textures" so they can easily be
// identified when debugging.
static int gID = 0;
return sk_atomic_dec(&gID) - 1;
}
GrGpu* GrMockGpu::Create(GrBackendContext backendContext, const GrContextOptions& contextOptions,
GrContext* context) {
static const GrMockOptions kDefaultOptions = GrMockOptions();
@ -42,10 +54,13 @@ GrMockGpu::GrMockGpu(GrContext* context, const GrMockOptions& options,
sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) {
bool hasMipLevels = texels.count() > 1;
GrMockTextureInfo info;
info.fID = NextInternalTextureID();
if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc, hasMipLevels));
return sk_sp<GrTexture>(
new GrMockTextureRenderTarget(this, budgeted, desc, hasMipLevels, info));
}
return sk_sp<GrTexture>(new GrMockTexture(this, budgeted, desc, hasMipLevels));
return sk_sp<GrTexture>(new GrMockTexture(this, budgeted, desc, hasMipLevels, info));
}
GrBuffer* GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrBufferType type,
@ -60,3 +75,22 @@ GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(const GrR
fStats.incStencilAttachmentCreates();
return new GrMockStencilAttachment(this, width, height, kBits, rt->numColorSamples());
}
GrBackendObject GrMockGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h,
GrPixelConfig config, bool isRT) {
auto info = new GrMockTextureInfo;
info->fID = NextExternalTextureID();
fOutstandingTestingOnlyTextureIDs.add(info->fID);
return reinterpret_cast<GrBackendObject>(info);
}
bool GrMockGpu::isTestingOnlyBackendTexture(GrBackendObject object) const {
return fOutstandingTestingOnlyTextureIDs.contains(
reinterpret_cast<const GrMockTextureInfo*>(object)->fID);
}
void GrMockGpu::deleteTestingOnlyBackendTexture(GrBackendObject object, bool abandonTexture) {
auto info = reinterpret_cast<const GrMockTextureInfo*>(object);
fOutstandingTestingOnlyTextureIDs.remove(info->fID);
delete info;
}

View File

@ -11,6 +11,7 @@
#include "GrGpu.h"
#include "GrSemaphore.h"
#include "GrTexture.h"
#include "SkTHash.h"
class GrMockGpuCommandBuffer;
struct GrMockOptions;
@ -120,12 +121,17 @@ private:
int height) override;
void clearStencil(GrRenderTarget* target) override {}
GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
GrPixelConfig config, bool isRT) override {
return 0;
}
bool isTestingOnlyBackendTexture(GrBackendObject ) const override { return false; }
void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override {}
GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig,
bool isRT) override;
bool isTestingOnlyBackendTexture(GrBackendObject) const override;
void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override;
static int NextInternalTextureID();
static int NextExternalTextureID();
SkTHashSet<int> fOutstandingTestingOnlyTextureIDs;
typedef GrGpu INHERITED;
};

View File

@ -10,11 +10,13 @@
#include "GrMockGpu.h"
#include "GrTexture.h"
#include "GrTexturePriv.h"
#include "mock/GrMockTypes.h"
class GrMockTexture : public GrTexture {
public:
GrMockTexture(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, bool hasMipLevels)
: GrMockTexture(gpu, desc, hasMipLevels) {
GrMockTexture(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, bool hasMipLevels,
const GrMockTextureInfo& info)
: GrMockTexture(gpu, desc, hasMipLevels, info) {
this->registerWithCache(budgeted);
}
~GrMockTexture() override {
@ -22,7 +24,9 @@ public:
fReleaseProc(fReleaseCtx);
}
}
GrBackendObject getTextureHandle() const override { return 0; }
GrBackendObject getTextureHandle() const override {
return reinterpret_cast<GrBackendObject>(&fInfo);
}
void textureParamsModified() override {}
void setRelease(ReleaseProc proc, ReleaseCtx ctx) override {
fReleaseProc = proc;
@ -31,14 +35,17 @@ public:
protected:
// constructor for subclasses
GrMockTexture(GrMockGpu* gpu, const GrSurfaceDesc& desc, bool hasMipLevels)
GrMockTexture(GrMockGpu* gpu, const GrSurfaceDesc& desc, bool hasMipLevels,
const GrMockTextureInfo& info)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, kITexture2DSampler_GrSLType, GrSamplerParams::kMipMap_FilterMode,
hasMipLevels)
, fInfo(info)
, fReleaseProc(nullptr)
, fReleaseCtx(nullptr) {}
private:
GrMockTextureInfo fInfo;
ReleaseProc fReleaseProc;
ReleaseCtx fReleaseCtx;
@ -48,9 +55,9 @@ private:
class GrMockTextureRenderTarget : public GrMockTexture, public GrRenderTarget {
public:
GrMockTextureRenderTarget(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
bool hasMipLevels)
bool hasMipLevels, const GrMockTextureInfo& texInfo)
: GrSurface(gpu, desc)
, GrMockTexture(gpu, desc, hasMipLevels)
, GrMockTexture(gpu, desc, hasMipLevels, texInfo)
, GrRenderTarget(gpu, desc) {
this->registerWithCache(budgeted);
}

View File

@ -323,15 +323,24 @@ static GrBackendTexture make_backend_texture_from_handle(GrBackend backend,
int width, int height,
GrPixelConfig config,
GrBackendObject handle) {
switch (backend) {
case kOpenGL_GrBackend: {
const GrGLTextureInfo* glInfo = (const GrGLTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *glInfo);
}
#ifdef SK_VULKAN
if (kVulkan_GrBackend == backend) {
GrVkImageInfo* vkInfo = (GrVkImageInfo*)(handle);
return GrBackendTexture(width, height, *vkInfo);
}
case kVulkan_GrBackend: {
const GrVkImageInfo* vkInfo = (const GrVkImageInfo*)(handle);
return GrBackendTexture(width, height, *vkInfo);
}
#endif
SkASSERT(kOpenGL_GrBackend == backend);
GrGLTextureInfo* glInfo = (GrGLTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *glInfo);
case kMock_GrBackend: {
const GrMockTextureInfo* mockInfo = (const GrMockTextureInfo*)(handle);
return GrBackendTexture(width, height, config, *mockInfo);
}
default:
return GrBackendTexture();
}
}
static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpace colorSpace,

View File

@ -75,12 +75,50 @@ DEF_TEST(ParseConfigs_DefaultConfigs, reporter) {
// Parses all default configs and returns correct "tag".
SkCommandLineFlags::StringArray config1 = make_string_array({
"565", "8888", "debuggl", "gl", "gldft", "nullgl", "glmsaa8", "glmsaa4",
"nonrendering", "nullgl", "gles", "glnvpr8", "glnvpr4", "glnvprdit8", "glesnvprdit4",
"pdf", "skp", "svg", "xps", "angle_d3d11_es2", "angle_gl_es2", "commandbuffer", "mesa",
"hwui", "glf16", "glessrgb", "gl", "glnvpr4", "glnvprdit4", "glsrgb", "glmsaa4", "vk",
"glinst", "glinst4", "glinstdit4", "glinst8", "glinstdit8", "glesinst", "glesinst4",
"glesinstdit4", "glwide", "glnarrow", "glnostencils"
"565",
"8888",
"debuggl",
"gl",
"gldft",
"nullgl",
"glmsaa8",
"glmsaa4",
"nonrendering",
"nullgl",
"gles",
"glnvpr8",
"glnvpr4",
"glnvprdit8",
"glesnvprdit4",
"pdf",
"skp",
"svg",
"xps",
"angle_d3d11_es2",
"angle_gl_es2",
"commandbuffer",
"mesa",
"hwui",
"glf16",
"glessrgb",
"gl",
"glnvpr4",
"glnvprdit4",
"glsrgb",
"glmsaa4",
"vk",
"glinst",
"glinst4",
"glinstdit4",
"glinst8",
"glinstdit8",
"glesinst",
"glesinst4",
"glesinstdit4",
"glwide",
"glnarrow",
"glnostencils",
"mock"
});
SkCommandLineConfigArray configs;
@ -147,6 +185,12 @@ DEF_TEST(ParseConfigs_DefaultConfigs, reporter) {
REPORTER_ASSERT(reporter, configs[41]->asConfigGpu()->getColorSpace()->gammaIsLinear());
REPORTER_ASSERT(reporter, *as_CSB(configs[41]->asConfigGpu()->getColorSpace())->toXYZD50() !=
*as_CSB(srgbColorSpace)->toXYZD50());
REPORTER_ASSERT(reporter, configs[42]->asConfigGpu()->getContextType() ==
GrContextFactory::kGL_ContextType);
REPORTER_ASSERT(reporter, SkToBool(configs[42]->asConfigGpu()->getContextOverrides() &
SkCommandLineConfigGpu::ContextOverrides::kAvoidStencilBuffers));
REPORTER_ASSERT(reporter, configs[43]->asConfigGpu()->getContextType() ==
GrContextFactory::kMock_ContextType);
REPORTER_ASSERT(reporter, configs[32]->asConfigGpu()->getUseInstanced());
REPORTER_ASSERT(reporter, configs[33]->asConfigGpu()->getContextType() ==
GrContextFactory::kGL_ContextType);
@ -215,6 +259,7 @@ DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) {
"gpu[api=gles]",
"gpu[api=gl]",
"gpu[api=vulkan]",
"gpu[api=mock]",
});
SkCommandLineConfigArray configs;
@ -260,6 +305,8 @@ DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) {
REPORTER_ASSERT(reporter, !configs[7]->asConfigGpu()->getUseDIText());
REPORTER_ASSERT(reporter, configs[7]->asConfigGpu()->getSamples() == 0);
#endif
REPORTER_ASSERT(reporter, configs[8]->asConfigGpu()->getContextType() ==
GrContextFactory::kMock_ContextType);
#endif
}

View File

@ -81,7 +81,8 @@ static const struct {
{ "angle_d3d11_es3_msaa8", "gpu", "api=angle_d3d11_es3,samples=8" },
{ "angle_gl_es2", "gpu", "api=angle_gl_es2" },
{ "angle_gl_es3", "gpu", "api=angle_gl_es3" },
{ "commandbuffer", "gpu", "api=commandbuffer" }
{ "commandbuffer", "gpu", "api=commandbuffer" },
{ "mock", "gpu", "api=mock" }
#if SK_MESA
,{ "mesa", "gpu", "api=mesa" }
#endif
@ -92,9 +93,8 @@ static const struct {
,{ "vkmsaa4", "gpu", "api=vulkan,samples=4" }
,{ "vkmsaa8", "gpu", "api=vulkan,samples=8" }
#endif
#else
{ "", "", "" }
{ "", "", "" }
#endif
};
@ -120,7 +120,6 @@ static const char configExtendedHelp[] =
"\tapi\ttype: string\trequired\n"
"\t Select graphics API to use with gpu backend.\n"
"\t Options:\n"
"\t\tnative\t\t\tUse platform default OpenGL or OpenGL ES backend.\n"
"\t\tgl \t\t\tUse OpenGL.\n"
"\t\tgles \t\t\tUse OpenGL ES.\n"
"\t\tdebuggl \t\t\tUse debug OpenGL.\n"
@ -131,6 +130,7 @@ static const char configExtendedHelp[] =
"\t\tangle_gl_es2\t\t\tUse OpenGL ES2 on the ANGLE OpenGL backend.\n"
"\t\tangle_gl_es3\t\t\tUse OpenGL ES3 on the ANGLE OpenGL backend.\n"
"\t\tcommandbuffer\t\tUse command buffer.\n"
"\t\tmock\t\tUse mock context.\n"
#if SK_MESA
"\t\tmesa\t\t\tUse MESA.\n"
#endif
@ -284,6 +284,10 @@ static bool parse_option_gpu_api(const SkString& value,
*outContextType = GrContextFactory::kCommandBuffer_ContextType;
return true;
}
if (value.equals("mock")) {
*outContextType = GrContextFactory::kMock_ContextType;
return true;
}
#if SK_MESA
if (value.equals("mesa")) {
*outContextType = GrContextFactory::kMESA_ContextType;