gfx/skia/trunk/src/views/win/SkOSWindow_win.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.

     2 /*
     3  * Copyright 2011 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
     8 #include "SkTypes.h"
    10 #if defined(SK_BUILD_FOR_WIN)
    12 #include <GL/gl.h>
    13 #include <WindowsX.h>
    14 #include "SkWGL.h"
    15 #include "SkWindow.h"
    16 #include "SkCanvas.h"
    17 #include "SkOSMenu.h"
    18 #include "SkTime.h"
    19 #include "SkUtils.h"
    21 #include "SkGraphics.h"
    23 #if SK_ANGLE
    24 #include "gl/GrGLInterface.h"
    26 #include "GLES2/gl2.h"
    28 #define ANGLE_GL_CALL(IFACE, X)                                 \
    29     do {                                                        \
    30         (IFACE)->fFunctions.f##X;                               \
    31     } while (false)
    33 #endif
    35 #define INVALIDATE_DELAY_MS 200
    37 static SkOSWindow* gCurrOSWin;
    38 static HWND gEventTarget;
    40 #define WM_EVENT_CALLBACK (WM_USER+0)
    42 void post_skwinevent()
    43 {
    44     PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0);
    45 }
    47 SkOSWindow::SkOSWindow(void* hWnd) {
    48     fHWND = hWnd;
    49 #if SK_SUPPORT_GPU
    50 #if SK_ANGLE
    51     fDisplay = EGL_NO_DISPLAY;
    52     fContext = EGL_NO_CONTEXT;
    53     fSurface = EGL_NO_SURFACE;
    54 #endif
    55     fHGLRC = NULL;
    56 #endif
    57     fAttached = kNone_BackEndType;
    58     gEventTarget = (HWND)hWnd;
    59 }
    61 SkOSWindow::~SkOSWindow() {
    62 #if SK_SUPPORT_GPU
    63     if (NULL != fHGLRC) {
    64         wglDeleteContext((HGLRC)fHGLRC);
    65     }
    66 #if SK_ANGLE
    67     if (EGL_NO_CONTEXT != fContext) {
    68         eglDestroyContext(fDisplay, fContext);
    69         fContext = EGL_NO_CONTEXT;
    70     }
    72     if (EGL_NO_SURFACE != fSurface) {
    73         eglDestroySurface(fDisplay, fSurface);
    74         fSurface = EGL_NO_SURFACE;
    75     }
    77     if (EGL_NO_DISPLAY != fDisplay) {
    78         eglTerminate(fDisplay);
    79         fDisplay = EGL_NO_DISPLAY;
    80     }
    81 #endif // SK_ANGLE
    82 #endif // SK_SUPPORT_GPU
    83 }
    85 static SkKey winToskKey(WPARAM vk) {
    86     static const struct {
    87         WPARAM    fVK;
    88         SkKey    fKey;
    89     } gPair[] = {
    90         { VK_BACK,    kBack_SkKey },
    91         { VK_CLEAR,    kBack_SkKey },
    92         { VK_RETURN, kOK_SkKey },
    93         { VK_UP,     kUp_SkKey },
    94         { VK_DOWN,     kDown_SkKey },
    95         { VK_LEFT,     kLeft_SkKey },
    96         { VK_RIGHT,     kRight_SkKey }
    97     };
    98     for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
    99         if (gPair[i].fVK == vk) {
   100             return gPair[i].fKey;
   101         }
   102     }
   103     return kNONE_SkKey;
   104 }
   106 static unsigned getModifiers(UINT message) {
   107     return 0;   // TODO
   108 }
   110 bool SkOSWindow::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
   111     switch (message) {
   112         case WM_KEYDOWN: {
   113             SkKey key = winToskKey(wParam);
   114             if (kNONE_SkKey != key) {
   115                 this->handleKey(key);
   116                 return true;
   117             }
   118         } break;
   119         case WM_KEYUP: {
   120             SkKey key = winToskKey(wParam);
   121             if (kNONE_SkKey != key) {
   122                 this->handleKeyUp(key);
   123                 return true;
   124             }
   125         } break;
   126         case WM_UNICHAR:
   127             this->handleChar((SkUnichar) wParam);
   128             return true;
   129         case WM_CHAR: {
   130             this->handleChar(SkUTF8_ToUnichar((char*)&wParam));
   131             return true;
   132         } break;
   133         case WM_SIZE: {
   134             INT width = LOWORD(lParam);
   135             INT height = HIWORD(lParam);
   136             this->resize(width, height);
   137             break;
   138         }
   139         case WM_PAINT: {
   140             PAINTSTRUCT ps;
   141             HDC hdc = BeginPaint(hWnd, &ps);
   142             this->doPaint(hdc);
   143             EndPaint(hWnd, &ps);
   144             return true;
   145             } break;
   147         case WM_TIMER: {
   148             RECT* rect = (RECT*)wParam;
   149             InvalidateRect(hWnd, rect, FALSE);
   150             KillTimer(hWnd, (UINT_PTR)rect);
   151             delete rect;
   152             return true;
   153         } break;
   155         case WM_LBUTTONDOWN:
   156             this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
   157                               Click::kDown_State, NULL, getModifiers(message));
   158             return true;
   160         case WM_MOUSEMOVE:
   161             this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
   162                               Click::kMoved_State, NULL, getModifiers(message));
   163             return true;
   165         case WM_LBUTTONUP:
   166             this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
   167                               Click::kUp_State, NULL, getModifiers(message));
   168             return true;
   170         case WM_EVENT_CALLBACK:
   171             if (SkEvent::ProcessEvent()) {
   172                 post_skwinevent();
   173             }
   174             return true;
   175     }
   176     return false;
   177 }
   179 void SkOSWindow::doPaint(void* ctx) {
   180     this->update(NULL);
   182     if (kNone_BackEndType == fAttached)
   183     {
   184         HDC hdc = (HDC)ctx;
   185         const SkBitmap& bitmap = this->getBitmap();
   187         BITMAPINFO bmi;
   188         memset(&bmi, 0, sizeof(bmi));
   189         bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
   190         bmi.bmiHeader.biWidth       = bitmap.width();
   191         bmi.bmiHeader.biHeight      = -bitmap.height(); // top-down image
   192         bmi.bmiHeader.biPlanes      = 1;
   193         bmi.bmiHeader.biBitCount    = 32;
   194         bmi.bmiHeader.biCompression = BI_RGB;
   195         bmi.bmiHeader.biSizeImage   = 0;
   197         //
   198         // Do the SetDIBitsToDevice.
   199         //
   200         // TODO(wjmaclean):
   201         //       Fix this call to handle SkBitmaps that have rowBytes != width,
   202         //       i.e. may have padding at the end of lines. The SkASSERT below
   203         //       may be ignored by builds, and the only obviously safe option
   204         //       seems to be to copy the bitmap to a temporary (contiguous)
   205         //       buffer before passing to SetDIBitsToDevice().
   206         SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
   207         bitmap.lockPixels();
   208         int ret = SetDIBitsToDevice(hdc,
   209             0, 0,
   210             bitmap.width(), bitmap.height(),
   211             0, 0,
   212             0, bitmap.height(),
   213             bitmap.getPixels(),
   214             &bmi,
   215             DIB_RGB_COLORS);
   216         (void)ret; // we're ignoring potential failures for now.
   217         bitmap.unlockPixels();
   218     }
   219 }
   221 #if 0
   222 void SkOSWindow::updateSize()
   223 {
   224     RECT    r;
   225     GetWindowRect((HWND)this->getHWND(), &r);
   226     this->resize(r.right - r.left, r.bottom - r.top);
   227 }
   228 #endif
   230 void SkOSWindow::onHandleInval(const SkIRect& r) {
   231     RECT* rect = new RECT;
   232     rect->left    = r.fLeft;
   233     rect->top     = r.fTop;
   234     rect->right   = r.fRight;
   235     rect->bottom  = r.fBottom;
   236     SetTimer((HWND)fHWND, (UINT_PTR)rect, INVALIDATE_DELAY_MS, NULL);
   237 }
   239 void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
   240 {
   241 }
   243 void SkOSWindow::onSetTitle(const char title[]){
   244     SetWindowTextA((HWND)fHWND, title);
   245 }
   247 enum {
   248     SK_MacReturnKey     = 36,
   249     SK_MacDeleteKey     = 51,
   250     SK_MacEndKey        = 119,
   251     SK_MacLeftKey       = 123,
   252     SK_MacRightKey      = 124,
   253     SK_MacDownKey       = 125,
   254     SK_MacUpKey         = 126,
   256     SK_Mac0Key          = 0x52,
   257     SK_Mac1Key          = 0x53,
   258     SK_Mac2Key          = 0x54,
   259     SK_Mac3Key          = 0x55,
   260     SK_Mac4Key          = 0x56,
   261     SK_Mac5Key          = 0x57,
   262     SK_Mac6Key          = 0x58,
   263     SK_Mac7Key          = 0x59,
   264     SK_Mac8Key          = 0x5b,
   265     SK_Mac9Key          = 0x5c
   266 };
   268 static SkKey raw2key(uint32_t raw)
   269 {
   270     static const struct {
   271         uint32_t  fRaw;
   272         SkKey   fKey;
   273     } gKeys[] = {
   274         { SK_MacUpKey,      kUp_SkKey       },
   275         { SK_MacDownKey,    kDown_SkKey     },
   276         { SK_MacLeftKey,    kLeft_SkKey     },
   277         { SK_MacRightKey,   kRight_SkKey    },
   278         { SK_MacReturnKey,  kOK_SkKey       },
   279         { SK_MacDeleteKey,  kBack_SkKey     },
   280         { SK_MacEndKey,     kEnd_SkKey      },
   281         { SK_Mac0Key,       k0_SkKey        },
   282         { SK_Mac1Key,       k1_SkKey        },
   283         { SK_Mac2Key,       k2_SkKey        },
   284         { SK_Mac3Key,       k3_SkKey        },
   285         { SK_Mac4Key,       k4_SkKey        },
   286         { SK_Mac5Key,       k5_SkKey        },
   287         { SK_Mac6Key,       k6_SkKey        },
   288         { SK_Mac7Key,       k7_SkKey        },
   289         { SK_Mac8Key,       k8_SkKey        },
   290         { SK_Mac9Key,       k9_SkKey        }
   291     };
   293     for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
   294         if (gKeys[i].fRaw == raw)
   295             return gKeys[i].fKey;
   296     return kNONE_SkKey;
   297 }
   299 ///////////////////////////////////////////////////////////////////////////////////////
   301 void SkEvent::SignalNonEmptyQueue()
   302 {
   303     post_skwinevent();
   304     //SkDebugf("signal nonempty\n");
   305 }
   307 static UINT_PTR gTimer;
   309 VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
   310 {
   311     SkEvent::ServiceQueueTimer();
   312     //SkDebugf("timer task fired\n");
   313 }
   315 void SkEvent::SignalQueueTimer(SkMSec delay)
   316 {
   317     if (gTimer)
   318     {
   319         KillTimer(NULL, gTimer);
   320         gTimer = NULL;
   321     }
   322     if (delay)
   323     {
   324         gTimer = SetTimer(NULL, 0, delay, sk_timer_proc);
   325         //SkDebugf("SetTimer of %d returned %d\n", delay, gTimer);
   326     }
   327 }
   329 #if SK_SUPPORT_GPU
   331 bool SkOSWindow::attachGL(int msaaSampleCount, AttachmentInfo* info) {
   332     HDC dc = GetDC((HWND)fHWND);
   333     if (NULL == fHGLRC) {
   334         fHGLRC = SkCreateWGLContext(dc, msaaSampleCount, false);
   335         if (NULL == fHGLRC) {
   336             return false;
   337         }
   338         glClearStencil(0);
   339         glClearColor(0, 0, 0, 0);
   340         glStencilMask(0xffffffff);
   341         glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
   342     }
   343     if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) {
   344         // use DescribePixelFormat to get the stencil bit depth.
   345         int pixelFormat = GetPixelFormat(dc);
   346         PIXELFORMATDESCRIPTOR pfd;
   347         DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
   348         info->fStencilBits = pfd.cStencilBits;
   350         // Get sample count if the MSAA WGL extension is present
   351         SkWGLExtensions extensions;
   352         if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
   353             static const int kSampleCountAttr = SK_WGL_SAMPLES;
   354             extensions.getPixelFormatAttribiv(dc,
   355                                               pixelFormat,
   356                                               0,
   357                                               1,
   358                                               &kSampleCountAttr,
   359                                               &info->fSampleCount);
   360         } else {
   361             info->fSampleCount = 0;
   362         }
   364         glViewport(0, 0,
   365                    SkScalarRoundToInt(this->width()),
   366                    SkScalarRoundToInt(this->height()));
   367         return true;
   368     }
   369     return false;
   370 }
   372 void SkOSWindow::detachGL() {
   373     wglMakeCurrent(GetDC((HWND)fHWND), 0);
   374     wglDeleteContext((HGLRC)fHGLRC);
   375     fHGLRC = NULL;
   376 }
   378 void SkOSWindow::presentGL() {
   379     glFlush();
   380     HDC dc = GetDC((HWND)fHWND);
   381     SwapBuffers(dc);
   382     ReleaseDC((HWND)fHWND, dc);
   383 }
   385 #if SK_ANGLE
   386 bool create_ANGLE(EGLNativeWindowType hWnd,
   387                   int msaaSampleCount,
   388                   EGLDisplay* eglDisplay,
   389                   EGLContext* eglContext,
   390                   EGLSurface* eglSurface,
   391                   EGLConfig* eglConfig) {
   392     static const EGLint contextAttribs[] = {
   393         EGL_CONTEXT_CLIENT_VERSION, 2,
   394         EGL_NONE, EGL_NONE
   395     };
   396     static const EGLint configAttribList[] = {
   397         EGL_RED_SIZE,       8,
   398         EGL_GREEN_SIZE,     8,
   399         EGL_BLUE_SIZE,      8,
   400         EGL_ALPHA_SIZE,     8,
   401         EGL_DEPTH_SIZE,     8,
   402         EGL_STENCIL_SIZE,   8,
   403         EGL_NONE
   404     };
   405     static const EGLint surfaceAttribList[] = {
   406         EGL_NONE, EGL_NONE
   407     };
   409     EGLDisplay display = eglGetDisplay(GetDC(hWnd));
   410     if (display == EGL_NO_DISPLAY ) {
   411        return false;
   412     }
   414     // Initialize EGL
   415     EGLint majorVersion, minorVersion;
   416     if (!eglInitialize(display, &majorVersion, &minorVersion)) {
   417        return false;
   418     }
   420     EGLint numConfigs;
   421     if (!eglGetConfigs(display, NULL, 0, &numConfigs)) {
   422        return false;
   423     }
   425     // Choose config
   426     bool foundConfig = false;
   427     if (msaaSampleCount) {
   428         static const int kConfigAttribListCnt =
   429                                 SK_ARRAY_COUNT(configAttribList);
   430         EGLint msaaConfigAttribList[kConfigAttribListCnt + 4];
   431         memcpy(msaaConfigAttribList,
   432                configAttribList,
   433                sizeof(configAttribList));
   434         SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]);
   435         msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS;
   436         msaaConfigAttribList[kConfigAttribListCnt + 0] = 1;
   437         msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES;
   438         msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount;
   439         msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE;
   440         if (eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) {
   441             SkASSERT(numConfigs > 0);
   442             foundConfig = true;
   443         }
   444     }
   445     if (!foundConfig) {
   446         if (!eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) {
   447            return false;
   448         }
   449     }
   451     // Create a surface
   452     EGLSurface surface = eglCreateWindowSurface(display, *eglConfig,
   453                                                 (EGLNativeWindowType)hWnd,
   454                                                 surfaceAttribList);
   455     if (surface == EGL_NO_SURFACE) {
   456        return false;
   457     }
   459     // Create a GL context
   460     EGLContext context = eglCreateContext(display, *eglConfig,
   461                                           EGL_NO_CONTEXT,
   462                                           contextAttribs );
   463     if (context == EGL_NO_CONTEXT ) {
   464        return false;
   465     }
   467     // Make the context current
   468     if (!eglMakeCurrent(display, surface, surface, context)) {
   469        return false;
   470     }
   472     *eglDisplay = display;
   473     *eglContext = context;
   474     *eglSurface = surface;
   475     return true;
   476 }
   478 bool SkOSWindow::attachANGLE(int msaaSampleCount, AttachmentInfo* info) {
   479     if (EGL_NO_DISPLAY == fDisplay) {
   480         bool bResult = create_ANGLE((HWND)fHWND,
   481                                     msaaSampleCount,
   482                                     &fDisplay,
   483                                     &fContext,
   484                                     &fSurface,
   485                                     &fConfig);
   486         if (false == bResult) {
   487             return false;
   488         }
   489         SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
   491         if (intf) {
   492             ANGLE_GL_CALL(intf, ClearStencil(0));
   493             ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0));
   494             ANGLE_GL_CALL(intf, StencilMask(0xffffffff));
   495             ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT));
   496         }
   497     }
   498     if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
   499         eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilBits);
   500         eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount);
   502         SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
   504         if (intf ) {
   505             ANGLE_GL_CALL(intf, Viewport(0, 0,
   506                                          SkScalarRoundToInt(this->width()),
   507                                          SkScalarRoundToInt(this->height())));
   508         }
   509         return true;
   510     }
   511     return false;
   512 }
   514 void SkOSWindow::detachANGLE() {
   515     eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT);
   517     eglDestroyContext(fDisplay, fContext);
   518     fContext = EGL_NO_CONTEXT;
   520     eglDestroySurface(fDisplay, fSurface);
   521     fSurface = EGL_NO_SURFACE;
   523     eglTerminate(fDisplay);
   524     fDisplay = EGL_NO_DISPLAY;
   525 }
   527 void SkOSWindow::presentANGLE() {
   528     SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
   530     if (intf) {
   531         ANGLE_GL_CALL(intf, Flush());
   532     }
   534     eglSwapBuffers(fDisplay, fSurface);
   535 }
   536 #endif // SK_ANGLE
   537 #endif // SK_SUPPORT_GPU
   539 // return true on success
   540 bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info) {
   542     // attach doubles as "windowResize" so we need to allo
   543     // already bound states to pass through again
   544     // TODO: split out the resize functionality
   545 //    SkASSERT(kNone_BackEndType == fAttached);
   546     bool result = true;
   548     switch (attachType) {
   549     case kNone_BackEndType:
   550         // nothing to do
   551         break;
   552 #if SK_SUPPORT_GPU
   553     case kNativeGL_BackEndType:
   554         result = attachGL(msaaSampleCount, info);
   555         break;
   556 #if SK_ANGLE
   557     case kANGLE_BackEndType:
   558         result = attachANGLE(msaaSampleCount, info);
   559         break;
   560 #endif // SK_ANGLE
   561 #endif // SK_SUPPORT_GPU
   562     default:
   563         SkASSERT(false);
   564         result = false;
   565         break;
   566     }
   568     if (result) {
   569         fAttached = attachType;
   570     }
   572     return result;
   573 }
   575 void SkOSWindow::detach() {
   576     switch (fAttached) {
   577     case kNone_BackEndType:
   578         // nothing to do
   579         break;
   580 #if SK_SUPPORT_GPU
   581     case kNativeGL_BackEndType:
   582         detachGL();
   583         break;
   584 #if SK_ANGLE
   585     case kANGLE_BackEndType:
   586         detachANGLE();
   587         break;
   588 #endif // SK_ANGLE
   589 #endif // SK_SUPPORT_GPU
   590     default:
   591         SkASSERT(false);
   592         break;
   593     }
   594     fAttached = kNone_BackEndType;
   595 }
   597 void SkOSWindow::present() {
   598     switch (fAttached) {
   599     case kNone_BackEndType:
   600         // nothing to do
   601         return;
   602 #if SK_SUPPORT_GPU
   603     case kNativeGL_BackEndType:
   604         presentGL();
   605         break;
   606 #if SK_ANGLE
   607     case kANGLE_BackEndType:
   608         presentANGLE();
   609         break;
   610 #endif // SK_ANGLE
   611 #endif // SK_SUPPORT_GPU
   612     default:
   613         SkASSERT(false);
   614         break;
   615     }
   616 }
   618 #endif

mercurial