Move clear-as-draw workaround to GrGLGpu and expose via GrContextOptions.
Bug: skia:7154 Change-Id: I23ffc11dab4a377fbd6b7e4e33722b3fa0793d58 Reviewed-on: https://skia-review.googlesource.com/60681 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
57caa660c0
commit
43f8bf0f78
@ -55,8 +55,6 @@ public:
|
|||||||
bool usesMixedSamples() const { return fUsesMixedSamples; }
|
bool usesMixedSamples() const { return fUsesMixedSamples; }
|
||||||
bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
|
bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
|
||||||
|
|
||||||
bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
|
|
||||||
|
|
||||||
bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
|
bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,7 +208,6 @@ protected:
|
|||||||
bool fMustClearUploadedBufferData : 1;
|
bool fMustClearUploadedBufferData : 1;
|
||||||
|
|
||||||
// Driver workaround
|
// Driver workaround
|
||||||
bool fUseDrawInsteadOfClear : 1;
|
|
||||||
bool fAvoidInstancedDrawsToFPTargets : 1;
|
bool fAvoidInstancedDrawsToFPTargets : 1;
|
||||||
bool fBlacklistCoverageCounting : 1;
|
bool fBlacklistCoverageCounting : 1;
|
||||||
bool fAvoidStencilBuffers : 1;
|
bool fAvoidStencilBuffers : 1;
|
||||||
|
@ -15,6 +15,17 @@
|
|||||||
class SkExecutor;
|
class SkExecutor;
|
||||||
|
|
||||||
struct GrContextOptions {
|
struct GrContextOptions {
|
||||||
|
enum class Enable {
|
||||||
|
/** Forces an option to be disabled. */
|
||||||
|
kNo,
|
||||||
|
/** Forces an option to be enabled. */
|
||||||
|
kYes,
|
||||||
|
/**
|
||||||
|
* Uses Skia's default behavior, which may use runtime properties (e.g. driver version).
|
||||||
|
*/
|
||||||
|
kDefault
|
||||||
|
};
|
||||||
|
|
||||||
GrContextOptions() {}
|
GrContextOptions() {}
|
||||||
|
|
||||||
// Suppress prints for the GrContext.
|
// Suppress prints for the GrContext.
|
||||||
@ -88,6 +99,12 @@ struct GrContextOptions {
|
|||||||
*/
|
*/
|
||||||
bool fAvoidStencilBuffers = false;
|
bool fAvoidStencilBuffers = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables driver workaround to use draws instead of glClear. This only applies to
|
||||||
|
* kOpenGL_GrBackend.
|
||||||
|
*/
|
||||||
|
Enable fUseDrawInsteadOfGLClear = Enable::kDefault;
|
||||||
|
|
||||||
#if GR_TEST_UTILS
|
#if GR_TEST_UTILS
|
||||||
/**
|
/**
|
||||||
* Private options that are only meant for testing within Skia's tools.
|
* Private options that are only meant for testing within Skia's tools.
|
||||||
|
@ -54,8 +54,6 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
|||||||
fFenceSyncSupport = false;
|
fFenceSyncSupport = false;
|
||||||
fCrossContextTextureSupport = false;
|
fCrossContextTextureSupport = false;
|
||||||
|
|
||||||
fUseDrawInsteadOfClear = false;
|
|
||||||
|
|
||||||
fInstancedSupport = InstancedSupport::kNone;
|
fInstancedSupport = InstancedSupport::kNone;
|
||||||
|
|
||||||
fBlendEquationSupport = kBasic_BlendEquationSupport;
|
fBlendEquationSupport = kBasic_BlendEquationSupport;
|
||||||
@ -148,7 +146,6 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
|
|||||||
writer->appendBool("Fence sync support", fFenceSyncSupport);
|
writer->appendBool("Fence sync support", fFenceSyncSupport);
|
||||||
writer->appendBool("Cross context texture support", fCrossContextTextureSupport);
|
writer->appendBool("Cross context texture support", fCrossContextTextureSupport);
|
||||||
|
|
||||||
writer->appendBool("Draw Instead of Clear [workaround]", fUseDrawInsteadOfClear);
|
|
||||||
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
|
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
|
||||||
fBlacklistCoverageCounting);
|
fBlacklistCoverageCounting);
|
||||||
writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes);
|
writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes);
|
||||||
|
@ -264,29 +264,14 @@ void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor
|
|||||||
// TODO: in a post-MDB world this should be handled at the OpList level.
|
// TODO: in a post-MDB world this should be handled at the OpList level.
|
||||||
// An op-list that is initially cleared and has no other ops should receive an
|
// An op-list that is initially cleared and has no other ops should receive an
|
||||||
// extra draw.
|
// extra draw.
|
||||||
if (fRenderTargetContext->fContext->caps()->useDrawInsteadOfClear()) {
|
// This path doesn't handle coalescing of full screen clears b.c. it
|
||||||
// This works around a driver bug with clear by drawing a rect instead.
|
// has to clear the entire render target - not just the content area.
|
||||||
// The driver will ignore a clear if it is the only thing rendered to a
|
// It could be done but will take more finagling.
|
||||||
// target before the target is read.
|
std::unique_ptr<GrOp> op(GrClearOp::Make(rtRect, color, !clearRect));
|
||||||
GrPaint paint;
|
if (!op) {
|
||||||
paint.setColor4f(GrColor4f::FromGrColor(color));
|
return;
|
||||||
paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
|
|
||||||
|
|
||||||
// We don't call drawRect() here to avoid the cropping to the, possibly smaller,
|
|
||||||
// RenderTargetProxy bounds
|
|
||||||
std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(
|
|
||||||
std::move(paint), SkMatrix::I(), SkRect::Make(rtRect), GrAAType::kNone);
|
|
||||||
fRenderTargetContext->addDrawOp(GrNoClip(), std::move(op));
|
|
||||||
} else {
|
|
||||||
// This path doesn't handle coalescing of full screen clears b.c. it
|
|
||||||
// has to clear the entire render target - not just the content area.
|
|
||||||
// It could be done but will take more finagling.
|
|
||||||
std::unique_ptr<GrOp> op(GrClearOp::Make(rtRect, color, !clearRect));
|
|
||||||
if (!op) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
|
|
||||||
}
|
}
|
||||||
|
fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
|
void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
|
||||||
@ -312,23 +297,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
|
|||||||
clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
|
clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fContext->caps()->useDrawInsteadOfClear()) {
|
if (isFull) {
|
||||||
// This works around a driver bug with clear by drawing a rect instead.
|
|
||||||
// The driver will ignore a clear if it is the only thing rendered to a
|
|
||||||
// target before the target is read.
|
|
||||||
SkIRect clearRect = SkIRect::MakeWH(this->width(), this->height());
|
|
||||||
if (isFull) {
|
|
||||||
this->discard();
|
|
||||||
} else if (!clearRect.intersect(clip.scissorRect())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrPaint paint;
|
|
||||||
paint.setColor4f(GrColor4f::FromGrColor(color));
|
|
||||||
paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
|
|
||||||
|
|
||||||
this->drawRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect));
|
|
||||||
} else if (isFull) {
|
|
||||||
this->getRTOpList()->fullClear(*this->caps(), color);
|
this->getRTOpList()->fullClear(*this->caps(), color);
|
||||||
} else {
|
} else {
|
||||||
std::unique_ptr<GrOp> op(GrClearOp::Make(clip, color, this->asSurfaceProxy()));
|
std::unique_ptr<GrOp> op(GrClearOp::Make(clip, color, this->asSurfaceProxy()));
|
||||||
@ -498,31 +467,28 @@ void GrRenderTargetContext::drawRect(const GrClip& clip,
|
|||||||
|
|
||||||
const SkStrokeRec& stroke = style->strokeRec();
|
const SkStrokeRec& stroke = style->strokeRec();
|
||||||
if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
|
if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
|
||||||
|
// Check if this is a full RT draw and can be replaced with a clear. We don't bother
|
||||||
if (!fContext->caps()->useDrawInsteadOfClear()) {
|
// checking cases where the RT is fully inside a stroke.
|
||||||
// Check if this is a full RT draw and can be replaced with a clear. We don't bother
|
SkRect rtRect = fRenderTargetProxy->getBoundsRect();
|
||||||
// checking cases where the RT is fully inside a stroke.
|
// Does the clip contain the entire RT?
|
||||||
SkRect rtRect = fRenderTargetProxy->getBoundsRect();
|
if (clip.quickContains(rtRect)) {
|
||||||
// Does the clip contain the entire RT?
|
SkMatrix invM;
|
||||||
if (clip.quickContains(rtRect)) {
|
if (!viewMatrix.invert(&invM)) {
|
||||||
SkMatrix invM;
|
return;
|
||||||
if (!viewMatrix.invert(&invM)) {
|
}
|
||||||
|
// Does the rect bound the RT?
|
||||||
|
GrQuad quad;
|
||||||
|
quad.setFromMappedRect(rtRect, invM);
|
||||||
|
if (rect_contains_inclusive(rect, quad.point(0)) &&
|
||||||
|
rect_contains_inclusive(rect, quad.point(1)) &&
|
||||||
|
rect_contains_inclusive(rect, quad.point(2)) &&
|
||||||
|
rect_contains_inclusive(rect, quad.point(3))) {
|
||||||
|
// Will it blend?
|
||||||
|
GrColor clearColor;
|
||||||
|
if (paint.isConstantBlendedColor(&clearColor)) {
|
||||||
|
this->clear(nullptr, clearColor, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Does the rect bound the RT?
|
|
||||||
GrQuad quad;
|
|
||||||
quad.setFromMappedRect(rtRect, invM);
|
|
||||||
if (rect_contains_inclusive(rect, quad.point(0)) &&
|
|
||||||
rect_contains_inclusive(rect, quad.point(1)) &&
|
|
||||||
rect_contains_inclusive(rect, quad.point(2)) &&
|
|
||||||
rect_contains_inclusive(rect, quad.point(3))) {
|
|
||||||
// Will it blend?
|
|
||||||
GrColor clearColor;
|
|
||||||
if (paint.isConstantBlendedColor(&clearColor)) {
|
|
||||||
this->clear(nullptr, clearColor, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
|
|||||||
fClearToBoundaryValuesIsBroken = false;
|
fClearToBoundaryValuesIsBroken = false;
|
||||||
fClearTextureSupport = false;
|
fClearTextureSupport = false;
|
||||||
fDrawArraysBaseVertexIsBroken = false;
|
fDrawArraysBaseVertexIsBroken = false;
|
||||||
|
fUseDrawToClearColor = false;
|
||||||
fUseDrawToClearStencilClip = false;
|
fUseDrawToClearStencilClip = false;
|
||||||
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
|
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
|
||||||
fUseDrawInsteadOfAllRenderTargetWrites = false;
|
fUseDrawInsteadOfAllRenderTargetWrites = false;
|
||||||
@ -565,7 +566,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
|||||||
kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
|
kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
|
||||||
(kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
|
(kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
|
||||||
ctxInfo.driver() != kChromium_GrGLDriver)) {
|
ctxInfo.driver() != kChromium_GrGLDriver)) {
|
||||||
fUseDrawInsteadOfClear = true;
|
fUseDrawToClearColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SK_BUILD_FOR_MAC
|
#ifdef SK_BUILD_FOR_MAC
|
||||||
@ -574,7 +575,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
|||||||
// crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
|
// crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
|
||||||
// perform full screen clears.
|
// perform full screen clears.
|
||||||
if (kIntel_GrGLVendor == ctxInfo.vendor()) {
|
if (kIntel_GrGLVendor == ctxInfo.vendor()) {
|
||||||
fUseDrawInsteadOfClear = true;
|
fUseDrawToClearColor = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -583,7 +584,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
|||||||
// See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
|
// See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
|
||||||
// but only for D3D11 ANGLE.
|
// but only for D3D11 ANGLE.
|
||||||
if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
|
if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
|
||||||
fUseDrawInsteadOfClear = true;
|
fUseDrawToClearColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
|
if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
|
||||||
@ -1389,6 +1390,8 @@ void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
|
|||||||
writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
|
writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
|
||||||
writer->appendBool("BGRA to RGBA readback conversions are slow",
|
writer->appendBool("BGRA to RGBA readback conversions are slow",
|
||||||
fRGBAToBGRAReadbackConversionsAreSlow);
|
fRGBAToBGRAReadbackConversionsAreSlow);
|
||||||
|
writer->appendBool("Draw To clear color", fUseDrawToClearColor);
|
||||||
|
writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
|
||||||
writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
|
writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
|
||||||
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
|
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
|
||||||
writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
|
writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
|
||||||
@ -2354,6 +2357,11 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
|
|||||||
if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
|
if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
|
||||||
fUseDrawInsteadOfAllRenderTargetWrites = true;
|
fUseDrawInsteadOfAllRenderTargetWrites = true;
|
||||||
}
|
}
|
||||||
|
if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
|
||||||
|
fUseDrawToClearColor = false;
|
||||||
|
} else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
|
||||||
|
fUseDrawToClearColor = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
|
int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
|
||||||
|
@ -376,6 +376,9 @@ public:
|
|||||||
// https://bugs.chromium.org/p/skia/issues/detail?id=6650
|
// https://bugs.chromium.org/p/skia/issues/detail?id=6650
|
||||||
bool drawArraysBaseVertexIsBroken() const { return fDrawArraysBaseVertexIsBroken; }
|
bool drawArraysBaseVertexIsBroken() const { return fDrawArraysBaseVertexIsBroken; }
|
||||||
|
|
||||||
|
// Many drivers have issues with color clears.
|
||||||
|
bool useDrawToClearColor() const { return fUseDrawToClearColor; }
|
||||||
|
|
||||||
/// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
|
/// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
|
||||||
/// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
|
/// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
|
||||||
/// op instead of using glClear seems to resolve the issue.
|
/// op instead of using glClear seems to resolve the issue.
|
||||||
@ -482,6 +485,7 @@ private:
|
|||||||
bool fClearToBoundaryValuesIsBroken : 1;
|
bool fClearToBoundaryValuesIsBroken : 1;
|
||||||
bool fClearTextureSupport : 1;
|
bool fClearTextureSupport : 1;
|
||||||
bool fDrawArraysBaseVertexIsBroken : 1;
|
bool fDrawArraysBaseVertexIsBroken : 1;
|
||||||
|
bool fUseDrawToClearColor : 1;
|
||||||
bool fUseDrawToClearStencilClip : 1;
|
bool fUseDrawToClearStencilClip : 1;
|
||||||
bool fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO : 1;
|
bool fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO : 1;
|
||||||
bool fUseDrawInsteadOfAllRenderTargetWrites : 1;
|
bool fUseDrawInsteadOfAllRenderTargetWrites : 1;
|
||||||
|
@ -218,14 +218,6 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
|
|||||||
, fStencilClearFBOID(0)
|
, fStencilClearFBOID(0)
|
||||||
, fHWMaxUsedBufferTextureUnit(-1)
|
, fHWMaxUsedBufferTextureUnit(-1)
|
||||||
, fHWMinSampleShading(0.0) {
|
, fHWMinSampleShading(0.0) {
|
||||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
|
|
||||||
fCopyPrograms[i].fProgram = 0;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
|
|
||||||
fMipmapPrograms[i].fProgram = 0;
|
|
||||||
}
|
|
||||||
fStencilClipClearProgram = 0;
|
|
||||||
|
|
||||||
SkASSERT(ctx);
|
SkASSERT(ctx);
|
||||||
fCaps.reset(SkRef(ctx->caps()));
|
fCaps.reset(SkRef(ctx->caps()));
|
||||||
|
|
||||||
@ -269,19 +261,19 @@ GrGLGpu::~GrGLGpu() {
|
|||||||
fMipmapProgramArrayBuffer.reset();
|
fMipmapProgramArrayBuffer.reset();
|
||||||
fStencilClipClearArrayBuffer.reset();
|
fStencilClipClearArrayBuffer.reset();
|
||||||
|
|
||||||
if (0 != fHWProgramID) {
|
if (fHWProgramID) {
|
||||||
// detach the current program so there is no confusion on OpenGL's part
|
// detach the current program so there is no confusion on OpenGL's part
|
||||||
// that we want it to be deleted
|
// that we want it to be deleted
|
||||||
GL_CALL(UseProgram(0));
|
GL_CALL(UseProgram(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != fTempSrcFBOID) {
|
if (fTempSrcFBOID) {
|
||||||
GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
|
GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
|
||||||
}
|
}
|
||||||
if (0 != fTempDstFBOID) {
|
if (fTempDstFBOID) {
|
||||||
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
||||||
}
|
}
|
||||||
if (0 != fStencilClearFBOID) {
|
if (fStencilClearFBOID) {
|
||||||
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
|
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,10 +289,14 @@ GrGLGpu::~GrGLGpu() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != fStencilClipClearProgram) {
|
if (fStencilClipClearProgram) {
|
||||||
GL_CALL(DeleteProgram(fStencilClipClearProgram));
|
GL_CALL(DeleteProgram(fStencilClipClearProgram));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fClearColorProgram.fProgram) {
|
||||||
|
GL_CALL(DeleteProgram(fClearColorProgram.fProgram));
|
||||||
|
}
|
||||||
|
|
||||||
delete fProgramCache;
|
delete fProgramCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +328,10 @@ void GrGLGpu::disconnect(DisconnectType type) {
|
|||||||
if (fStencilClipClearProgram) {
|
if (fStencilClipClearProgram) {
|
||||||
GL_CALL(DeleteProgram(fStencilClipClearProgram));
|
GL_CALL(DeleteProgram(fStencilClipClearProgram));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fClearColorProgram.fProgram) {
|
||||||
|
GL_CALL(DeleteProgram(fClearColorProgram.fProgram));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fProgramCache) {
|
if (fProgramCache) {
|
||||||
fProgramCache->abandon();
|
fProgramCache->abandon();
|
||||||
@ -355,6 +355,8 @@ void GrGLGpu::disconnect(DisconnectType type) {
|
|||||||
}
|
}
|
||||||
fStencilClipClearProgram = 0;
|
fStencilClipClearProgram = 0;
|
||||||
fStencilClipClearArrayBuffer.reset();
|
fStencilClipClearArrayBuffer.reset();
|
||||||
|
fClearColorProgram.fProgram = 0;
|
||||||
|
|
||||||
if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
|
if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
|
||||||
this->glPathRendering()->disconnect(type);
|
this->glPathRendering()->disconnect(type);
|
||||||
}
|
}
|
||||||
@ -1954,15 +1956,10 @@ void GrGLGpu::disableScissor() {
|
|||||||
|
|
||||||
void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
|
void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
|
||||||
GrRenderTarget* target, GrSurfaceOrigin origin) {
|
GrRenderTarget* target, GrSurfaceOrigin origin) {
|
||||||
this->handleDirtyContext();
|
|
||||||
|
|
||||||
// parent class should never let us get here with no RT
|
// parent class should never let us get here with no RT
|
||||||
SkASSERT(target);
|
SkASSERT(target);
|
||||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
|
||||||
|
|
||||||
this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
|
this->handleDirtyContext();
|
||||||
this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
|
|
||||||
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
|
|
||||||
|
|
||||||
GrGLfloat r, g, b, a;
|
GrGLfloat r, g, b, a;
|
||||||
static const GrGLfloat scale255 = 1.f / 255.f;
|
static const GrGLfloat scale255 = 1.f / 255.f;
|
||||||
@ -1972,6 +1969,17 @@ void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
|
|||||||
g = GrColorUnpackG(color) * scaleRGB;
|
g = GrColorUnpackG(color) * scaleRGB;
|
||||||
b = GrColorUnpackB(color) * scaleRGB;
|
b = GrColorUnpackB(color) * scaleRGB;
|
||||||
|
|
||||||
|
if (this->glCaps().useDrawToClearColor()) {
|
||||||
|
this->clearColorAsDraw(clip, r, g, b, a, target, origin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
||||||
|
|
||||||
|
this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
|
||||||
|
this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
|
||||||
|
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
|
||||||
|
|
||||||
GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
|
GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
|
||||||
fHWWriteToColor = kYes_TriState;
|
fHWWriteToColor = kYes_TriState;
|
||||||
|
|
||||||
@ -3855,6 +3863,123 @@ void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencil
|
|||||||
GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
|
GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GrGLGpu::createClearColorProgram() {
|
||||||
|
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||||
|
|
||||||
|
if (!fClearProgramArrayBuffer) {
|
||||||
|
static const GrGLfloat vdata[] = {-1, -1, 1, -1, -1, 1, 1, 1};
|
||||||
|
fClearProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
|
||||||
|
kStatic_GrAccessPattern, vdata));
|
||||||
|
if (!fClearProgramArrayBuffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkASSERT(!fClearColorProgram.fProgram);
|
||||||
|
GL_CALL_RET(fClearColorProgram.fProgram, CreateProgram());
|
||||||
|
if (!fClearColorProgram.fProgram) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier);
|
||||||
|
const char* version = this->caps()->shaderCaps()->versionDeclString();
|
||||||
|
|
||||||
|
SkString vshaderTxt(version);
|
||||||
|
aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
|
||||||
|
vshaderTxt.append(";");
|
||||||
|
vshaderTxt.append(R"(
|
||||||
|
// Clear Color Program VS
|
||||||
|
void main() {
|
||||||
|
sk_Position = float4(a_vertex.x, a_vertex.y, 0, 1);
|
||||||
|
})");
|
||||||
|
|
||||||
|
GrShaderVar uColor("u_color", kHalf4_GrSLType, GrShaderVar::kUniform_TypeModifier);
|
||||||
|
SkString fshaderTxt(version);
|
||||||
|
uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt);
|
||||||
|
fshaderTxt.append(";");
|
||||||
|
fshaderTxt.appendf(R"(
|
||||||
|
// Clear Color Program FS
|
||||||
|
void main() {
|
||||||
|
sk_FragColor = u_color;
|
||||||
|
})");
|
||||||
|
|
||||||
|
const char* str;
|
||||||
|
GrGLint length;
|
||||||
|
|
||||||
|
str = vshaderTxt.c_str();
|
||||||
|
length = SkToInt(vshaderTxt.size());
|
||||||
|
SkSL::Program::Settings settings;
|
||||||
|
settings.fCaps = this->caps()->shaderCaps();
|
||||||
|
SkSL::Program::Inputs inputs;
|
||||||
|
GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fClearColorProgram.fProgram,
|
||||||
|
GR_GL_VERTEX_SHADER, &str, &length, 1, &fStats,
|
||||||
|
settings, &inputs);
|
||||||
|
SkASSERT(inputs.isEmpty());
|
||||||
|
|
||||||
|
str = fshaderTxt.c_str();
|
||||||
|
length = SkToInt(fshaderTxt.size());
|
||||||
|
GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fClearColorProgram.fProgram,
|
||||||
|
GR_GL_FRAGMENT_SHADER, &str, &length, 1, &fStats,
|
||||||
|
settings, &inputs);
|
||||||
|
SkASSERT(inputs.isEmpty());
|
||||||
|
|
||||||
|
GL_CALL(LinkProgram(fClearColorProgram.fProgram));
|
||||||
|
|
||||||
|
GL_CALL(BindAttribLocation(fClearColorProgram.fProgram, 0, "a_vertex"));
|
||||||
|
|
||||||
|
GL_CALL_RET(fClearColorProgram.fColorUniform,
|
||||||
|
GetUniformLocation(fClearColorProgram.fProgram, "u_color"));
|
||||||
|
|
||||||
|
GL_CALL(DeleteShader(vshader));
|
||||||
|
GL_CALL(DeleteShader(fshader));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g, GrGLfloat b,
|
||||||
|
GrGLfloat a, GrRenderTarget* dst, GrSurfaceOrigin origin) {
|
||||||
|
if (!fClearColorProgram.fProgram) {
|
||||||
|
if (!this->createClearColorProgram()) {
|
||||||
|
SkDebugf("Failed to create clear color program.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GrGLIRect dstVP;
|
||||||
|
this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
|
||||||
|
this->flushViewport(dstVP);
|
||||||
|
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||||
|
|
||||||
|
GL_CALL(UseProgram(fClearColorProgram.fProgram));
|
||||||
|
fHWProgramID = fClearColorProgram.fProgram;
|
||||||
|
|
||||||
|
fHWVertexArrayState.setVertexArrayID(this, 0);
|
||||||
|
|
||||||
|
GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
|
||||||
|
attribs->enableVertexArrays(this, 1);
|
||||||
|
attribs->set(this, 0, fClearProgramArrayBuffer.get(), kHalf2_GrVertexAttribType,
|
||||||
|
2 * sizeof(GrGLfloat), 0);
|
||||||
|
|
||||||
|
GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(dst);
|
||||||
|
this->flushScissor(clip.scissorState(), glrt->getViewport(), origin);
|
||||||
|
this->flushWindowRectangles(clip.windowRectsState(), glrt, origin);
|
||||||
|
|
||||||
|
GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, r, g, b, a));
|
||||||
|
|
||||||
|
GrXferProcessor::BlendInfo blendInfo;
|
||||||
|
blendInfo.reset();
|
||||||
|
this->flushBlend(blendInfo, GrSwizzle::RGBA());
|
||||||
|
this->flushColorWrite(true);
|
||||||
|
this->flushHWAAState(nullptr, false, false);
|
||||||
|
this->disableStencil();
|
||||||
|
if (this->glCaps().srgbWriteControl()) {
|
||||||
|
this->flushFramebufferSRGB(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
|
||||||
|
this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst);
|
||||||
|
this->didWriteToSurface(dst, &clip.scissorState().rect());
|
||||||
|
}
|
||||||
|
|
||||||
bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||||
GrSurface* src, GrSurfaceOrigin srcOrigin,
|
GrSurface* src, GrSurfaceOrigin srcOrigin,
|
||||||
|
@ -135,6 +135,8 @@ public:
|
|||||||
// Thus this is the implementation of the clear call for the corresponding passthrough function
|
// Thus this is the implementation of the clear call for the corresponding passthrough function
|
||||||
// on GrGLGpuRTCommandBuffer.
|
// on GrGLGpuRTCommandBuffer.
|
||||||
void clear(const GrFixedClip&, GrColor, GrRenderTarget*, GrSurfaceOrigin);
|
void clear(const GrFixedClip&, GrColor, GrRenderTarget*, GrSurfaceOrigin);
|
||||||
|
void clearColorAsDraw(const GrFixedClip&, GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a,
|
||||||
|
GrRenderTarget*, GrSurfaceOrigin);
|
||||||
|
|
||||||
// The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
|
// The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
|
||||||
// Thus this is the implementation of the clearStencil call for the corresponding passthrough
|
// Thus this is the implementation of the clearStencil call for the corresponding passthrough
|
||||||
@ -420,6 +422,7 @@ private:
|
|||||||
bool createCopyProgram(GrTexture* srcTexture);
|
bool createCopyProgram(GrTexture* srcTexture);
|
||||||
bool createMipmapProgram(int progIdx);
|
bool createMipmapProgram(int progIdx);
|
||||||
bool createStencilClipClearProgram();
|
bool createStencilClipClearProgram();
|
||||||
|
bool createClearColorProgram();
|
||||||
|
|
||||||
// GL program-related state
|
// GL program-related state
|
||||||
ProgramCache* fProgramCache;
|
ProgramCache* fProgramCache;
|
||||||
@ -617,24 +620,31 @@ private:
|
|||||||
|
|
||||||
/** IDs for copy surface program. (4 sampler types) */
|
/** IDs for copy surface program. (4 sampler types) */
|
||||||
struct {
|
struct {
|
||||||
GrGLuint fProgram;
|
GrGLuint fProgram = 0;
|
||||||
GrGLint fTextureUniform;
|
GrGLint fTextureUniform = 0;
|
||||||
GrGLint fTexCoordXformUniform;
|
GrGLint fTexCoordXformUniform = 0;
|
||||||
GrGLint fPosXformUniform;
|
GrGLint fPosXformUniform = 0;
|
||||||
} fCopyPrograms[4];
|
} fCopyPrograms[4];
|
||||||
sk_sp<GrGLBuffer> fCopyProgramArrayBuffer;
|
sk_sp<GrGLBuffer> fCopyProgramArrayBuffer;
|
||||||
|
|
||||||
/** IDs for texture mipmap program. (4 filter configurations) */
|
/** IDs for texture mipmap program. (4 filter configurations) */
|
||||||
struct {
|
struct {
|
||||||
GrGLuint fProgram;
|
GrGLuint fProgram = 0;
|
||||||
GrGLint fTextureUniform;
|
GrGLint fTextureUniform = 0;
|
||||||
GrGLint fTexCoordXformUniform;
|
GrGLint fTexCoordXformUniform = 0;
|
||||||
} fMipmapPrograms[4];
|
} fMipmapPrograms[4];
|
||||||
sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer;
|
sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer;
|
||||||
|
|
||||||
GrGLuint fStencilClipClearProgram;
|
GrGLuint fStencilClipClearProgram = 0;
|
||||||
sk_sp<GrGLBuffer> fStencilClipClearArrayBuffer;
|
sk_sp<GrGLBuffer> fStencilClipClearArrayBuffer;
|
||||||
|
|
||||||
|
/** IDs for clear render target color program. */
|
||||||
|
struct {
|
||||||
|
GrGLuint fProgram = 0;
|
||||||
|
GrGLint fColorUniform = 0;
|
||||||
|
} fClearColorProgram;
|
||||||
|
sk_sp<GrGLBuffer> fClearProgramArrayBuffer;
|
||||||
|
|
||||||
static int TextureToCopyProgramIdx(GrTexture* texture);
|
static int TextureToCopyProgramIdx(GrTexture* texture);
|
||||||
|
|
||||||
static int TextureSizeToMipmapProgramIdx(int width, int height) {
|
static int TextureSizeToMipmapProgramIdx(int width, int height) {
|
||||||
|
@ -160,7 +160,6 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
|
|||||||
fUsesMixedSamples = false;
|
fUsesMixedSamples = false;
|
||||||
fGpuTracingSupport = false;
|
fGpuTracingSupport = false;
|
||||||
|
|
||||||
fUseDrawInsteadOfClear = false;
|
|
||||||
fFenceSyncSupport = true; // always available in Metal
|
fFenceSyncSupport = true; // always available in Metal
|
||||||
fCrossContextTextureSupport = false;
|
fCrossContextTextureSupport = false;
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
|
|||||||
fOversizedStencilSupport = false; //TODO: figure this out
|
fOversizedStencilSupport = false; //TODO: figure this out
|
||||||
fInstanceAttribSupport = true;
|
fInstanceAttribSupport = true;
|
||||||
|
|
||||||
fUseDrawInsteadOfClear = false;
|
|
||||||
fBlacklistCoverageCounting = true; // blacklisting ccpr until we work through a few issues.
|
fBlacklistCoverageCounting = true; // blacklisting ccpr until we work through a few issues.
|
||||||
fFenceSyncSupport = true; // always available in Vulkan
|
fFenceSyncSupport = true; // always available in Vulkan
|
||||||
fCrossContextTextureSupport = false;
|
fCrossContextTextureSupport = false;
|
||||||
|
@ -43,8 +43,7 @@ sk_sp<GrRenderTargetContext> newRTC(GrContext* context, int w, int h) {
|
|||||||
kRGBA_8888_GrPixelConfig, nullptr);
|
kRGBA_8888_GrPixelConfig, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
|
static void clear_op_test(skiatest::Reporter* reporter, GrContext* context) {
|
||||||
GrContext* context = ctxInfo.grContext();
|
|
||||||
static const int kW = 10;
|
static const int kW = 10;
|
||||||
static const int kH = 10;
|
static const int kH = 10;
|
||||||
|
|
||||||
@ -202,4 +201,84 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
|
|||||||
failX, failY);
|
failX, failY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
|
||||||
|
clear_op_test(reporter, ctxInfo.grContext());
|
||||||
|
if (ctxInfo.backend() == kOpenGL_GrBackend) {
|
||||||
|
GrContextOptions options(ctxInfo.options());
|
||||||
|
options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
|
||||||
|
sk_gpu_test::GrContextFactory workaroundFactory(options);
|
||||||
|
clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
void fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* context) {
|
||||||
|
const SkImageInfo ii = SkImageInfo::Make(400, 77, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||||
|
|
||||||
|
sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii);
|
||||||
|
SkCanvas* canvas = surf->getCanvas();
|
||||||
|
|
||||||
|
SkPaint paints[2];
|
||||||
|
paints[0].setColor(SK_ColorGREEN);
|
||||||
|
paints[1].setColor(SK_ColorGRAY);
|
||||||
|
|
||||||
|
static const int kLeftX = 158;
|
||||||
|
static const int kMidX = 258;
|
||||||
|
static const int kRightX = 383;
|
||||||
|
static const int kTopY = 26;
|
||||||
|
static const int kBotY = 51;
|
||||||
|
|
||||||
|
const SkRect rects[2] = {
|
||||||
|
{ kLeftX, kTopY, kMidX, kBotY },
|
||||||
|
{ kMidX, kTopY, kRightX, kBotY },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
// the bounds parameter is required to cause a full screen clear
|
||||||
|
canvas->saveLayer(&rects[i], nullptr);
|
||||||
|
canvas->drawRect(rects[i], paints[i]);
|
||||||
|
canvas->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
SkBitmap bm;
|
||||||
|
bm.allocPixels(ii, 0);
|
||||||
|
|
||||||
|
SkAssertResult(surf->readPixels(bm, 0, 0));
|
||||||
|
|
||||||
|
bool isCorrect = true;
|
||||||
|
for (int y = kTopY; isCorrect && y < kBotY; ++y) {
|
||||||
|
const uint32_t* sl = bm.getAddr32(0, y);
|
||||||
|
|
||||||
|
for (int x = kLeftX; x < kMidX; ++x) {
|
||||||
|
if (SK_ColorGREEN != sl[x]) {
|
||||||
|
isCorrect = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = kMidX; x < kRightX; ++x) {
|
||||||
|
if (SK_ColorGRAY != sl[x]) {
|
||||||
|
isCorrect = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REPORTER_ASSERT(reporter, isCorrect);
|
||||||
|
}
|
||||||
|
// From crbug.com/768134
|
||||||
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) {
|
||||||
|
fullscreen_clear_with_layer_test(reporter, ctxInfo.grContext());
|
||||||
|
if (ctxInfo.backend() == kOpenGL_GrBackend) {
|
||||||
|
GrContextOptions options(ctxInfo.options());
|
||||||
|
options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
|
||||||
|
sk_gpu_test::GrContextFactory workaroundFactory(options);
|
||||||
|
fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -517,11 +517,6 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(OnFlushCallbackTest, reporter, ctxInfo) {
|
|||||||
|
|
||||||
GrContext* context = ctxInfo.grContext();
|
GrContext* context = ctxInfo.grContext();
|
||||||
|
|
||||||
if (context->caps()->useDrawInsteadOfClear()) {
|
|
||||||
// TODO: fix the buffer issues so this can run on all devices
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AtlasObject object;
|
AtlasObject object;
|
||||||
|
|
||||||
// For now (until we add a GrSuperDeferredSimpleTextureEffect), we create the final atlas
|
// For now (until we add a GrSuperDeferredSimpleTextureEffect), we create the final atlas
|
||||||
|
@ -116,7 +116,8 @@ ContextInfo GrContextFactory::getContextInfoInternal(ContextType type, ContextOv
|
|||||||
context.fShareIndex == shareIndex &&
|
context.fShareIndex == shareIndex &&
|
||||||
!context.fAbandoned) {
|
!context.fAbandoned) {
|
||||||
context.fTestContext->makeCurrent();
|
context.fTestContext->makeCurrent();
|
||||||
return ContextInfo(context.fType, context.fTestContext, context.fGrContext);
|
return ContextInfo(context.fType, context.fTestContext, context.fGrContext,
|
||||||
|
context.fOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +289,8 @@ ContextInfo GrContextFactory::getContextInfoInternal(ContextType type, ContextOv
|
|||||||
context.fAbandoned = false;
|
context.fAbandoned = false;
|
||||||
context.fShareContext = shareContext;
|
context.fShareContext = shareContext;
|
||||||
context.fShareIndex = shareIndex;
|
context.fShareIndex = shareIndex;
|
||||||
return ContextInfo(context.fType, context.fTestContext, context.fGrContext);
|
context.fOptions = grOptions;
|
||||||
|
return ContextInfo(context.fType, context.fTestContext, context.fGrContext, context.fOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides overrides) {
|
ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides overrides) {
|
||||||
|
@ -159,6 +159,7 @@ private:
|
|||||||
struct Context {
|
struct Context {
|
||||||
ContextType fType;
|
ContextType fType;
|
||||||
ContextOverrides fOverrides;
|
ContextOverrides fOverrides;
|
||||||
|
GrContextOptions fOptions;
|
||||||
GrBackend fBackend;
|
GrBackend fBackend;
|
||||||
TestContext* fTestContext;
|
TestContext* fTestContext;
|
||||||
GrContext* fGrContext;
|
GrContext* fGrContext;
|
||||||
@ -189,19 +190,18 @@ public:
|
|||||||
return static_cast<GLTestContext*>(fTestContext);
|
return static_cast<GLTestContext*>(fTestContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GrContextOptions& options() const { return fOptions; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContextInfo(GrContextFactory::ContextType type,
|
ContextInfo(GrContextFactory::ContextType type, TestContext* testContext, GrContext* grContext,
|
||||||
TestContext* testContext,
|
const GrContextOptions& options)
|
||||||
GrContext* grContext)
|
: fType(type), fTestContext(testContext), fGrContext(grContext), fOptions(options) {}
|
||||||
: fType(type)
|
|
||||||
, fTestContext(testContext)
|
|
||||||
, fGrContext(grContext) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GrContextFactory::ContextType fType = GrContextFactory::kGL_ContextType;
|
GrContextFactory::ContextType fType = GrContextFactory::kGL_ContextType;
|
||||||
// Valid until the factory destroys it via abandonContexts() or destroyContexts().
|
// Valid until the factory destroys it via abandonContexts() or destroyContexts().
|
||||||
TestContext* fTestContext = nullptr;
|
TestContext* fTestContext = nullptr;
|
||||||
GrContext* fGrContext = nullptr;
|
GrContext* fGrContext = nullptr;
|
||||||
|
GrContextOptions fOptions;
|
||||||
|
|
||||||
friend class GrContextFactory;
|
friend class GrContextFactory;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user