Merge "Only have a single call into pdfium at a time." into nyc-mr1-dev

This commit is contained in:
Philip P. Moltmann
2016-08-19 23:03:23 +00:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 29 deletions

View File

@@ -52,11 +52,9 @@ static struct {
} gRectClassInfo; } gRectClassInfo;
// Also used in PdfRenderer.cpp // Also used in PdfRenderer.cpp
Mutex sPdfiumLock;
int sUnmatchedPdfiumInitRequestCount = 0; int sUnmatchedPdfiumInitRequestCount = 0;
static void initializeLibraryIfNeeded() { static void initializeLibraryIfNeeded() {
Mutex::Autolock _l(sPdfiumLock);
if (sUnmatchedPdfiumInitRequestCount == 0) { if (sUnmatchedPdfiumInitRequestCount == 0) {
FPDF_InitLibrary(); FPDF_InitLibrary();
} }
@@ -64,7 +62,6 @@ static void initializeLibraryIfNeeded() {
} }
static void destroyLibraryIfNeeded() { static void destroyLibraryIfNeeded() {
Mutex::Autolock _l(sPdfiumLock);
sUnmatchedPdfiumInitRequestCount--; sUnmatchedPdfiumInitRequestCount--;
if (sUnmatchedPdfiumInitRequestCount == 0) { if (sUnmatchedPdfiumInitRequestCount == 0) {
FPDF_DestroyLibrary(); FPDF_DestroyLibrary();

View File

@@ -44,11 +44,9 @@ static struct {
} gPointClassInfo; } gPointClassInfo;
// See PdfEditor.cpp // See PdfEditor.cpp
extern Mutex sPdfiumLock;
extern int sUnmatchedPdfiumInitRequestCount; extern int sUnmatchedPdfiumInitRequestCount;
static void initializeLibraryIfNeeded() { static void initializeLibraryIfNeeded() {
Mutex::Autolock _l(sPdfiumLock);
if (sUnmatchedPdfiumInitRequestCount == 0) { if (sUnmatchedPdfiumInitRequestCount == 0) {
FPDF_InitLibrary(); FPDF_InitLibrary();
} }
@@ -56,7 +54,6 @@ static void initializeLibraryIfNeeded() {
} }
static void destroyLibraryIfNeeded() { static void destroyLibraryIfNeeded() {
Mutex::Autolock _l(sPdfiumLock);
sUnmatchedPdfiumInitRequestCount--; sUnmatchedPdfiumInitRequestCount--;
if (sUnmatchedPdfiumInitRequestCount == 0) { if (sUnmatchedPdfiumInitRequestCount == 0) {
FPDF_DestroyLibrary(); FPDF_DestroyLibrary();

View File

@@ -79,8 +79,12 @@ public final class PdfEditor {
} }
mInput = input; mInput = input;
synchronized (PdfRenderer.sPdfiumLock) {
mNativeDocument = nativeOpen(mInput.getFd(), size); mNativeDocument = nativeOpen(mInput.getFd(), size);
mPageCount = nativeGetPageCount(mNativeDocument); mPageCount = nativeGetPageCount(mNativeDocument);
}
mCloseGuard.open("close"); mCloseGuard.open("close");
} }
@@ -102,8 +106,11 @@ public final class PdfEditor {
public void removePage(int pageIndex) { public void removePage(int pageIndex) {
throwIfClosed(); throwIfClosed();
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
mPageCount = nativeRemovePage(mNativeDocument, pageIndex); mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
} }
}
/** /**
* Sets a transformation and clip for a given page. The transformation matrix if * Sets a transformation and clip for a given page. The transformation matrix if
@@ -125,13 +132,18 @@ public final class PdfEditor {
if (clip == null) { if (clip == null) {
Point size = new Point(); Point size = new Point();
getPageSize(pageIndex, size); getPageSize(pageIndex, size);
synchronized (PdfRenderer.sPdfiumLock) {
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance, nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
0, 0, size.x, size.y); 0, 0, size.x, size.y);
}
} else { } else {
synchronized (PdfRenderer.sPdfiumLock) {
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance, nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
clip.left, clip.top, clip.right, clip.bottom); clip.left, clip.top, clip.right, clip.bottom);
} }
} }
}
/** /**
* Gets the size of a given page in mils (1/72"). * Gets the size of a given page in mils (1/72").
@@ -143,8 +155,11 @@ public final class PdfEditor {
throwIfClosed(); throwIfClosed();
throwIfOutSizeNull(outSize); throwIfOutSizeNull(outSize);
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
nativeGetPageSize(mNativeDocument, pageIndex, outSize); nativeGetPageSize(mNativeDocument, pageIndex, outSize);
} }
}
/** /**
* Gets the media box of a given page in mils (1/72"). * Gets the media box of a given page in mils (1/72").
@@ -156,8 +171,11 @@ public final class PdfEditor {
throwIfClosed(); throwIfClosed();
throwIfOutMediaBoxNull(outMediaBox); throwIfOutMediaBoxNull(outMediaBox);
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox); return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
} }
}
/** /**
* Sets the media box of a given page in mils (1/72"). * Sets the media box of a given page in mils (1/72").
@@ -169,8 +187,11 @@ public final class PdfEditor {
throwIfClosed(); throwIfClosed();
throwIfMediaBoxNull(mediaBox); throwIfMediaBoxNull(mediaBox);
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox); nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
} }
}
/** /**
* Gets the crop box of a given page in mils (1/72"). * Gets the crop box of a given page in mils (1/72").
@@ -182,8 +203,11 @@ public final class PdfEditor {
throwIfClosed(); throwIfClosed();
throwIfOutCropBoxNull(outCropBox); throwIfOutCropBoxNull(outCropBox);
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox); return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
} }
}
/** /**
* Sets the crop box of a given page in mils (1/72"). * Sets the crop box of a given page in mils (1/72").
@@ -195,8 +219,11 @@ public final class PdfEditor {
throwIfClosed(); throwIfClosed();
throwIfCropBoxNull(cropBox); throwIfCropBoxNull(cropBox);
throwIfPageNotInDocument(pageIndex); throwIfPageNotInDocument(pageIndex);
synchronized (PdfRenderer.sPdfiumLock) {
nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox); nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
} }
}
/** /**
* Gets whether the document prefers to be scaled for printing. * Gets whether the document prefers to be scaled for printing.
@@ -205,8 +232,11 @@ public final class PdfEditor {
*/ */
public boolean shouldScaleForPrinting() { public boolean shouldScaleForPrinting() {
throwIfClosed(); throwIfClosed();
synchronized (PdfRenderer.sPdfiumLock) {
return nativeScaleForPrinting(mNativeDocument); return nativeScaleForPrinting(mNativeDocument);
} }
}
/** /**
* Writes the PDF file to the provided destination. * Writes the PDF file to the provided destination.
@@ -219,7 +249,10 @@ public final class PdfEditor {
public void write(ParcelFileDescriptor output) throws IOException { public void write(ParcelFileDescriptor output) throws IOException {
try { try {
throwIfClosed(); throwIfClosed();
synchronized (PdfRenderer.sPdfiumLock) {
nativeWrite(mNativeDocument, output.getFd()); nativeWrite(mNativeDocument, output.getFd());
}
} finally { } finally {
IoUtils.closeQuietly(output); IoUtils.closeQuietly(output);
} }
@@ -247,7 +280,9 @@ public final class PdfEditor {
} }
private void doClose() { private void doClose() {
synchronized (PdfRenderer.sPdfiumLock) {
nativeClose(mNativeDocument); nativeClose(mNativeDocument);
}
IoUtils.closeQuietly(mInput); IoUtils.closeQuietly(mInput);
mInput = null; mInput = null;
mCloseGuard.close(); mCloseGuard.close();

View File

@@ -99,6 +99,12 @@ import java.lang.annotation.RetentionPolicy;
* @see #close() * @see #close()
*/ */
public final class PdfRenderer implements AutoCloseable { public final class PdfRenderer implements AutoCloseable {
/**
* Any call the native pdfium code has to be single threaded as the library does not support
* parallel use.
*/
final static Object sPdfiumLock = new Object();
private final CloseGuard mCloseGuard = CloseGuard.get(); private final CloseGuard mCloseGuard = CloseGuard.get();
private final Point mTempPoint = new Point(); private final Point mTempPoint = new Point();
@@ -154,8 +160,12 @@ public final class PdfRenderer implements AutoCloseable {
} }
mInput = input; mInput = input;
synchronized (sPdfiumLock) {
mNativeDocument = nativeCreate(mInput.getFd(), size); mNativeDocument = nativeCreate(mInput.getFd(), size);
mPageCount = nativeGetPageCount(mNativeDocument); mPageCount = nativeGetPageCount(mNativeDocument);
}
mCloseGuard.open("close"); mCloseGuard.open("close");
} }
@@ -189,8 +199,11 @@ public final class PdfRenderer implements AutoCloseable {
*/ */
public boolean shouldScaleForPrinting() { public boolean shouldScaleForPrinting() {
throwIfClosed(); throwIfClosed();
synchronized (sPdfiumLock) {
return nativeScaleForPrinting(mNativeDocument); return nativeScaleForPrinting(mNativeDocument);
} }
}
/** /**
* Opens a page for rendering. * Opens a page for rendering.
@@ -224,7 +237,9 @@ public final class PdfRenderer implements AutoCloseable {
if (mCurrentPage != null) { if (mCurrentPage != null) {
mCurrentPage.close(); mCurrentPage.close();
} }
synchronized (sPdfiumLock) {
nativeClose(mNativeDocument); nativeClose(mNativeDocument);
}
try { try {
mInput.close(); mInput.close();
} catch (IOException ioe) { } catch (IOException ioe) {
@@ -277,7 +292,9 @@ public final class PdfRenderer implements AutoCloseable {
private Page(int index) { private Page(int index) {
Point size = mTempPoint; Point size = mTempPoint;
synchronized (sPdfiumLock) {
mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size); mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size);
}
mIndex = index; mIndex = index;
mWidth = size.x; mWidth = size.x;
mHeight = size.y; mHeight = size.y;
@@ -384,9 +401,11 @@ public final class PdfRenderer implements AutoCloseable {
final long transformPtr = (transform != null) ? transform.native_instance : 0; final long transformPtr = (transform != null) ? transform.native_instance : 0;
synchronized (sPdfiumLock) {
nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft, nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
contentTop, contentRight, contentBottom, transformPtr, renderMode); contentTop, contentRight, contentBottom, transformPtr, renderMode);
} }
}
/** /**
* Closes this page. * Closes this page.
@@ -412,7 +431,9 @@ public final class PdfRenderer implements AutoCloseable {
} }
private void doClose() { private void doClose() {
synchronized (sPdfiumLock) {
nativeClosePage(mNativePage); nativeClosePage(mNativePage);
}
mNativePage = 0; mNativePage = 0;
mCloseGuard.close(); mCloseGuard.close();
mCurrentPage = null; mCurrentPage = null;