Bug 1287666 - Avoid a round trip to the X server in nsShmImage::CreateDrawTarget. r=lsalzman

MozReview-Commit-ID: LpvsntOCMab

--HG--
extra : rebase_source : e13ad6f33b875bcae59110347b696ea640085bbb
This commit is contained in:
Andrew Comminos 2016-07-21 13:41:09 -04:00
Родитель 46650a73f4
Коммит 8bec715c96
2 изменённых файлов: 32 добавлений и 23 удалений

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;