gfx/angle/src/libEGL/Surface.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 //
     2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
     3 // Use of this source code is governed by a BSD-style license that can be
     4 // found in the LICENSE file.
     5 //
     7 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
     8 // such as the client area of a window, including any back buffers.
     9 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
    11 #include <tchar.h>
    13 #include "libEGL/Surface.h"
    15 #include "common/debug.h"
    16 #include "libGLESv2/Texture.h"
    17 #include "libGLESv2/renderer/SwapChain.h"
    18 #include "libGLESv2/main.h"
    20 #include "libEGL/main.h"
    21 #include "libEGL/Display.h"
    23 #include <algorithm>
    25 namespace egl
    26 {
    28 Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported) 
    29     : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
    30 {
    31     mRenderer = mDisplay->getRenderer();
    32     mSwapChain = NULL;
    33     mShareHandle = NULL;
    34     mTexture = NULL;
    35     mTextureFormat = EGL_NO_TEXTURE;
    36     mTextureTarget = EGL_NO_TEXTURE;
    38     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    39     mRenderBuffer = EGL_BACK_BUFFER;
    40     mSwapBehavior = EGL_BUFFER_PRESERVED;
    41     mSwapInterval = -1;
    42     mWidth = -1;
    43     mHeight = -1;
    44     setSwapInterval(1);
    46     subclassWindow();
    47 }
    49 Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
    50     : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
    51 {
    52     mRenderer = mDisplay->getRenderer();
    53     mSwapChain = NULL;
    54     mWindowSubclassed = false;
    55     mTexture = NULL;
    56     mTextureFormat = textureFormat;
    57     mTextureTarget = textureType;
    59     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    60     mRenderBuffer = EGL_BACK_BUFFER;
    61     mSwapBehavior = EGL_BUFFER_PRESERVED;
    62     mSwapInterval = -1;
    63     setSwapInterval(1);
    64 }
    66 Surface::~Surface()
    67 {
    68     unsubclassWindow();
    69     release();
    70 }
    72 bool Surface::initialize()
    73 {
    74     if (!resetSwapChain())
    75       return false;
    77     return true;
    78 }
    80 void Surface::release()
    81 {
    82     delete mSwapChain;
    83     mSwapChain = NULL;
    85     if (mTexture)
    86     {
    87         mTexture->releaseTexImage();
    88         mTexture = NULL;
    89     }
    90 }
    92 bool Surface::resetSwapChain()
    93 {
    94     ASSERT(!mSwapChain);
    96     int width;
    97     int height;
    99     if (mWindow)
   100     {
   101         RECT windowRect;
   102         if (!GetClientRect(getWindowHandle(), &windowRect))
   103         {
   104             ASSERT(false);
   106             ERR("Could not retrieve the window dimensions");
   107             return error(EGL_BAD_SURFACE, false);
   108         }
   110         width = windowRect.right - windowRect.left;
   111         height = windowRect.bottom - windowRect.top;
   112     }
   113     else
   114     {
   115         // non-window surface - size is determined at creation
   116         width = mWidth;
   117         height = mHeight;
   118     }
   120     mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
   121                                             mConfig->mRenderTargetFormat,
   122                                             mConfig->mDepthStencilFormat);
   123     if (!mSwapChain)
   124     {
   125         return error(EGL_BAD_ALLOC, false);
   126     }
   128     if (!resetSwapChain(width, height))
   129     {
   130         delete mSwapChain;
   131         mSwapChain = NULL;
   132         return false;
   133     }
   135     return true;
   136 }
   138 bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
   139 {
   140     ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
   141     ASSERT(mSwapChain);
   143     EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
   145     if (status == EGL_CONTEXT_LOST)
   146     {
   147         mDisplay->notifyDeviceLost();
   148         return false;
   149     }
   150     else if (status != EGL_SUCCESS)
   151     {
   152         return error(status, false);
   153     }
   155     mWidth = backbufferWidth;
   156     mHeight = backbufferHeight;
   158     return true;
   159 }
   161 bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
   162 {
   163     ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
   164     ASSERT(mSwapChain);
   166     EGLint status = mSwapChain->reset(backbufferWidth, backbufferHeight, mSwapInterval);
   168     if (status == EGL_CONTEXT_LOST)
   169     {
   170         mRenderer->notifyDeviceLost();
   171         return false;
   172     }
   173     else if (status != EGL_SUCCESS)
   174     {
   175         return error(status, false);
   176     }
   178     mWidth = backbufferWidth;
   179     mHeight = backbufferHeight;
   180     mSwapIntervalDirty = false;
   182     return true;
   183 }
   185 bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
   186 {
   187     if (!mSwapChain)
   188     {
   189         return true;
   190     }
   192     if (x + width > mWidth)
   193     {
   194         width = mWidth - x;
   195     }
   197     if (y + height > mHeight)
   198     {
   199         height = mHeight - y;
   200     }
   202     if (width == 0 || height == 0)
   203     {
   204         return true;
   205     }
   207     EGLint status = mSwapChain->swapRect(x, y, width, height);
   209     if (status == EGL_CONTEXT_LOST)
   210     {
   211         mRenderer->notifyDeviceLost();
   212         return false;
   213     }
   214     else if (status != EGL_SUCCESS)
   215     {
   216         return error(status, false);
   217     }
   219     checkForOutOfDateSwapChain();
   221     return true;
   222 }
   224 HWND Surface::getWindowHandle()
   225 {
   226     return mWindow;
   227 }
   230 #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
   231 #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
   233 static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
   234 {
   235   if (message == WM_SIZE)
   236   {
   237       Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
   238       if(surf)
   239       {
   240           surf->checkForOutOfDateSwapChain();
   241       }
   242   }
   243   WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
   244   return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
   245 }
   247 void Surface::subclassWindow()
   248 {
   249     if (!mWindow)
   250     {
   251         return;
   252     }
   254     DWORD processId;
   255     DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
   256     if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
   257     {
   258         return;
   259     }
   261     SetLastError(0);
   262     LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
   263     if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
   264     {
   265         mWindowSubclassed = false;
   266         return;
   267     }
   269     SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
   270     SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
   271     mWindowSubclassed = true;
   272 }
   274 void Surface::unsubclassWindow()
   275 {
   276     if(!mWindowSubclassed)
   277     {
   278         return;
   279     }
   281     // un-subclass
   282     LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
   284     // Check the windowproc is still SurfaceWindowProc.
   285     // If this assert fails, then it is likely the application has subclassed the
   286     // hwnd as well and did not unsubclass before destroying its EGL context. The
   287     // application should be modified to either subclass before initializing the
   288     // EGL context, or to unsubclass before destroying the EGL context.
   289     if(parentWndFunc)
   290     {
   291         LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
   292         ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
   293     }
   295     RemoveProp(mWindow, kSurfaceProperty);
   296     RemoveProp(mWindow, kParentWndProc);
   297     mWindowSubclassed = false;
   298 }
   300 bool Surface::checkForOutOfDateSwapChain()
   301 {
   302     RECT client;
   303     if (!GetClientRect(getWindowHandle(), &client))
   304     {
   305         ASSERT(false);
   306         return false;
   307     }
   309     // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
   310     int clientWidth = client.right - client.left;
   311     int clientHeight = client.bottom - client.top;
   312     bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
   314     if (mSwapIntervalDirty)
   315     {
   316         resetSwapChain(clientWidth, clientHeight);
   317     }
   318     else if (sizeDirty)
   319     {
   320         resizeSwapChain(clientWidth, clientHeight);
   321     }
   323     if (mSwapIntervalDirty || sizeDirty)
   324     {
   325         if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
   326         {
   327             glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
   328         }
   330         return true;
   331     }
   333     return false;
   334 }
   336 bool Surface::swap()
   337 {
   338     return swapRect(0, 0, mWidth, mHeight);
   339 }
   341 bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
   342 {
   343     if (!mPostSubBufferSupported)
   344     {
   345         // Spec is not clear about how this should be handled.
   346         return true;
   347     }
   349     return swapRect(x, y, width, height);
   350 }
   352 EGLint Surface::getWidth() const
   353 {
   354     return mWidth;
   355 }
   357 EGLint Surface::getHeight() const
   358 {
   359     return mHeight;
   360 }
   362 EGLint Surface::isPostSubBufferSupported() const
   363 {
   364     return mPostSubBufferSupported;
   365 }
   367 rx::SwapChain *Surface::getSwapChain() const
   368 {
   369     return mSwapChain;
   370 }
   372 void Surface::setSwapInterval(EGLint interval)
   373 {
   374     if (mSwapInterval == interval)
   375     {
   376         return;
   377     }
   379     mSwapInterval = interval;
   380     mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
   381     mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());
   383     mSwapIntervalDirty = true;
   384 }
   386 EGLenum Surface::getTextureFormat() const
   387 {
   388     return mTextureFormat;
   389 }
   391 EGLenum Surface::getTextureTarget() const
   392 {
   393     return mTextureTarget;
   394 }
   396 void Surface::setBoundTexture(gl::Texture2D *texture)
   397 {
   398     mTexture = texture;
   399 }
   401 gl::Texture2D *Surface::getBoundTexture() const
   402 {
   403     return mTexture;
   404 }
   406 EGLenum Surface::getFormat() const
   407 {
   408     return mConfig->mRenderTargetFormat;
   409 }
   410 }

mercurial