OSDN Git Service

Fixed synchronization issue on MacOS
authorAlexis Hetu <sugoi@google.com>
Mon, 4 Jun 2018 15:38:17 +0000 (11:38 -0400)
committerAlexis Hétu <sugoi@google.com>
Mon, 4 Jun 2018 16:50:37 +0000 (16:50 +0000)
Because of the way SwiftShader is integrated into Chromium on MacOS,
a synchronization issue exists when Chromium attempts to use an
IOSurface before SwiftShader is done rendering into it. In order to
solve this, all draw calls that end up rendering into an IOSurface
must be synchronized within SwiftShader and can't yield to Chromium
until rendering is complete.

Bug chromium:847094

Change-Id: If2dba4fa998e7437ec414d3b4aff9e8b19ecc128
Reviewed-on: https://swiftshader-review.googlesource.com/19188
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/OpenGL/common/Image.cpp
src/Renderer/Renderer.cpp
src/Renderer/Surface.hpp

index 601876e..447222c 100644 (file)
@@ -1332,6 +1332,15 @@ namespace egl
 #endif
        }
 
+       bool ClientBuffer::targetRequiresSync() const
+       {
+#if defined(__APPLE__)
+               return true;
+#else
+               return false;
+#endif
+       }
+
        class ClientBufferImage : public egl::Image
        {
        public:
@@ -1422,6 +1431,11 @@ namespace egl
                        sw::Surface::unlockExternal();
                }
 
+               bool targetRequiresSync() const override
+               {
+                       return clientBuffer.targetRequiresSync();
+               }
+
                void release() override
                {
                        Image::release();
index 7282e38..1334e70 100644 (file)
@@ -224,6 +224,7 @@ namespace sw
 
                int ss = context->getSuperSampleCount();
                int ms = context->getMultiSampleCount();
+               bool targetRequiresSync = false;
 
                for(int q = 0; q < ss; q++)
                {
@@ -607,6 +608,7 @@ namespace sw
                                        if(draw->renderTarget[index])
                                        {
                                                unsigned int layer = context->renderTargetLayer[index];
+                                               targetRequiresSync |= context->renderTarget[index]->targetRequiresSync();
                                                data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
                                                data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true);
                                                data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB();
@@ -620,6 +622,7 @@ namespace sw
                                if(draw->depthBuffer)
                                {
                                        unsigned int layer = context->depthBufferLayer;
+                                       targetRequiresSync |= context->depthBuffer->targetRequiresSync();
                                        data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
                                        data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true);
                                        data->depthPitchB = context->depthBuffer->getInternalPitchB();
@@ -629,6 +632,7 @@ namespace sw
                                if(draw->stencilBuffer)
                                {
                                        unsigned int layer = context->stencilBufferLayer;
+                                       targetRequiresSync |= context->stencilBuffer->targetRequiresSync();
                                        data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, layer, MANAGED);
                                        data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true);
                                        data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
@@ -675,6 +679,12 @@ namespace sw
                                }
                        }
                }
+
+               // TODO(sugoi): This is a temporary brute-force workaround to ensure IOSurface synchronization.
+               if(targetRequiresSync)
+               {
+                       synchronize();
+               }
        }
 
        void Renderer::clear(void *value, Format format, Surface *dest, const Rect &clearRect, unsigned int rgbaMask)
index eedffc2..2b1b906 100644 (file)
@@ -321,6 +321,7 @@ namespace sw
                inline int getStencilSliceB() const;
 
                void sync();                      // Wait for lock(s) to be released.
+               virtual bool targetRequiresSync() const { return false; }
                inline bool isUnlocked() const;   // Only reliable after sync().
 
                inline int getSamples() const;