From 8bec715c9675099ffec3ce23937e029e2efd594d Mon Sep 17 00:00:00 2001 From: Andrew Comminos Date: Thu, 21 Jul 2016 13:41:09 -0400 Subject: [PATCH] Bug 1287666 - Avoid a round trip to the X server in nsShmImage::CreateDrawTarget. r=lsalzman MozReview-Commit-ID: LpvsntOCMab --HG-- extra : rebase_source : e13ad6f33b875bcae59110347b696ea640085bbb --- widget/nsShmImage.cpp | 51 ++++++++++++++++++++++++------------------- widget/nsShmImage.h | 4 +++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/widget/nsShmImage.cpp b/widget/nsShmImage.cpp index 86b136634f58..74c3517dd66c 100644 --- a/widget/nsShmImage.cpp +++ b/widget/nsShmImage.cpp @@ -32,18 +32,14 @@ nsShmImage::nsShmImage(Display* aDisplay, , mSize(0, 0) , mPixmap(XCB_NONE) , mGC(XCB_NONE) + , mRequestPending(false) , mShmSeg(XCB_NONE) , mShmId(-1) , mShmAddr(nullptr) { mConnection = XGetXCBConnection(aDisplay); - mozilla::PodZero(&mLastRequest); - if (aDisplay == mozilla::DefaultXDisplay()) { - // If another thread spins the X event loop during a checked call, - // an error that should've been checked by XCB may be handled by the Xlib - // error handler. See bug 1287463. - NS_WARNING("Main thread X display used with nsShmImage!"); - } + mozilla::PodZero(&mPutRequest); + mozilla::PodZero(&mSyncRequest); } nsShmImage::~nsShmImage() @@ -250,13 +246,19 @@ nsShmImage::CreateDrawTarget(const mozilla::LayoutDeviceIntRegion& aRegion) // Wait for any in-flight requests to complete. // Typically X clients would wait for a XShmCompletionEvent to be received, // but this works as it's sent immediately after the request is processed. - xcb_generic_error_t* error; - if (mLastRequest.sequence != XCB_NONE && - (error = xcb_request_check(mConnection, mLastRequest))) - { - gShmAvailable = false; - free(error); - return nullptr; + if (mRequestPending) { + xcb_get_input_focus_reply_t* reply; + if ((reply = xcb_get_input_focus_reply(mConnection, mSyncRequest, nullptr))) { + free(reply); + } + mRequestPending = false; + + xcb_generic_error_t* error; + if ((error = xcb_request_check(mConnection, mPutRequest))) { + gShmAvailable = false; + free(error); + return nullptr; + } } // Due to bug 1205045, we must avoid making GTK calls off the main thread to query window size. @@ -301,17 +303,22 @@ nsShmImage::Put(const mozilla::LayoutDeviceIntRegion& aRegion) xrects.Length(), xrects.Elements()); if (mPixmap != XCB_NONE) { - mLastRequest = xcb_copy_area_checked(mConnection, mPixmap, mWindow, mGC, - 0, 0, 0, 0, mSize.width, mSize.height); + mPutRequest = xcb_copy_area_checked(mConnection, mPixmap, mWindow, mGC, + 0, 0, 0, 0, mSize.width, mSize.height); } else { - mLastRequest = xcb_shm_put_image_checked(mConnection, mWindow, mGC, - mSize.width, mSize.height, - 0, 0, mSize.width, mSize.height, - 0, 0, mDepth, - XCB_IMAGE_FORMAT_Z_PIXMAP, 0, - mShmSeg, 0); + mPutRequest = xcb_shm_put_image_checked(mConnection, mWindow, mGC, + mSize.width, mSize.height, + 0, 0, mSize.width, mSize.height, + 0, 0, mDepth, + XCB_IMAGE_FORMAT_Z_PIXMAP, 0, + mShmSeg, 0); } + // Send a request that returns a response so that we don't have to start a + // sync in nsShmImage::CreateDrawTarget to retrieve the result of mPutRequest. + mSyncRequest = xcb_get_input_focus(mConnection); + mRequestPending = true; + xcb_flush(mConnection); } diff --git a/widget/nsShmImage.h b/widget/nsShmImage.h index 5be968fe1717..129a2d08c2fd 100644 --- a/widget/nsShmImage.h +++ b/widget/nsShmImage.h @@ -58,7 +58,9 @@ private: xcb_pixmap_t mPixmap; xcb_gcontext_t mGC; - xcb_void_cookie_t mLastRequest; + xcb_void_cookie_t mPutRequest; + xcb_get_input_focus_cookie_t mSyncRequest; + bool mRequestPending; xcb_shm_seg_t mShmSeg; int mShmId;