diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/gradients/SkSweepGradient.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrShaderCaps.cpp | 1 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 15 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 10 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 7 |
5 files changed, 42 insertions, 5 deletions
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 1608ae2f72..64778c3a54 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -210,8 +210,18 @@ void GrSweepGradient::GLSLSweepProcessor::emitCode(EmitArgs& args) { SkString coords2D = args.fFragBuilder->ensureCoords2D(args.fTransformedCoords[0]); SkString t; // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] - t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)", - coords2D.c_str(), coords2D.c_str()); + if (args.fShaderCaps->atan2ImplementedAsAtanYOverX()) { + // On some devices they incorrectly implement atan2(y,x) as atan(y/x). In actuality it is + // atan2(y,x) = 2 * atan(y / (sqrt(x^2 + y^2) + x)). So to work around this we pass in + // (sqrt(x^2 + y^2) + x) as the second parameter to atan2 in these cases. We let the device + // handle the undefined behavior of the second paramenter being 0 instead of doing the + // divide ourselves and using atan instead. + t.printf("(2.0 * atan(- %s.y, length(%s) - %s.x) * 0.1591549430918 + 0.5)", + coords2D.c_str(), coords2D.c_str(), coords2D.c_str()); + } else { + t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)", + coords2D.c_str(), coords2D.c_str()); + } this->emitColor(args.fFragBuilder, args.fUniformHandler, args.fShaderCaps, diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp index f9db968e3f..54cd3e53cd 100644 --- a/src/gpu/GrShaderCaps.cpp +++ b/src/gpu/GrShaderCaps.cpp @@ -56,6 +56,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) { fCanUseAnyFunctionInShader = true; fCanUseMinAndAbsTogether = true; fMustForceNegatedAtanParamToFloat = false; + fAtan2ImplementedAsAtanYOverX = false; fRequiresLocalOutputColorForFBFetch = false; fFlatInterpolationSupport = false; fNoPerspectiveInterpolationSupport = false; diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index f614ae39c6..383d3caf49 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -19,6 +19,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* fMustDoCopiesFromOrigin = false; fSupportsCopiesAsDraws = false; fMustSubmitCommandsBeforeCopyOp = false; + fMustSleepOnTearDown = false; /************************************************************************** * GrDrawTargetCaps fields @@ -79,6 +80,16 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* fMustSubmitCommandsBeforeCopyOp = true; } +#if defined(SK_BUILD_FOR_WIN) + if (kNvidia_VkVendor == properties.vendorID) { + fMustSleepOnTearDown = true; + } +#elif defined(SK_BUILD_FOR_ANDROID) + if (kImagination_VkVendor == properties.vendorID) { + fMustSleepOnTearDown = true; + } +#endif + this->applyOptionsOverrides(contextOptions); fShaderCaps->applyOptionsOverrides(contextOptions); } @@ -163,6 +174,10 @@ void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint } } + if (kImagination_VkVendor == properties.vendorID) { + shaderCaps->fAtan2ImplementedAsAtanYOverX = true; + } + // Vulkan is based off ES 3.0 so the following should all be supported shaderCaps->fUsesPrecisionModifiers = true; shaderCaps->fFlatInterpolationSupport = true; diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index b390a9b2af..6d030f69a1 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -76,6 +76,10 @@ public: return fMustSubmitCommandsBeforeCopyOp; } + bool mustSleepOnTearDown() const { + return fMustSleepOnTearDown; + } + /** * Returns both a supported and most prefered stencil format to use in draws. */ @@ -87,6 +91,7 @@ private: enum VkVendor { kQualcomm_VkVendor = 20803, kNvidia_VkVendor = 4318, + kImagination_VkVendor = 4112, }; void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, @@ -136,6 +141,11 @@ private: // as draws. bool fMustSubmitCommandsBeforeCopyOp; + // Sometimes calls to QueueWaitIdle return before actually signalling the fences + // on the command buffers even though they have completed. This causes an assert to fire when + // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. + bool fMustSleepOnTearDown; + typedef GrCaps INHERITED; }; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 853e68cc00..b94a37957f 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -168,12 +168,13 @@ GrVkGpu::~GrVkGpu() { // destroying the command buffers. Currently this ony seems to happen on windows, so we add a // sleep to make sure the fence signals. #ifdef SK_DEBUG + if (this->vkCaps().mustSleepOnTearDown()) { #if defined(SK_BUILD_FOR_WIN) - Sleep(10); // In milliseconds + Sleep(10); // In milliseconds #else - // Uncomment if above bug happens on non windows build. - // sleep(1); // In seconds + sleep(1); // In seconds #endif + } #endif #ifdef SK_DEBUG |