[PDF] Fix memory hungry inefficiency in pdf resource tracking.
When moving the content of a device into a PDF object like SkPDFFormXObject or SkPDFShader does, we only need the top level resources in the new object's resource list, not the recursive set of objects. Otherwise, when you put a form on a form on form, etc, references to the objects multiply. This fixed http://crbug.com/117321 Review URL: https://codereview.appspot.com/5796048 git-svn-id: http://skia.googlecode.com/svn/trunk@3360 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a2d8014e66
commit
188838c208
@ -124,8 +124,12 @@ public:
|
||||
|
||||
/** Get the list of resources (PDF objects) used on this page.
|
||||
* @param resourceList A list to append the resources to.
|
||||
* @param recursive If recursive is true, get the resources of the
|
||||
* device's resources recursively. (Useful for adding
|
||||
* objects to the catalog.)
|
||||
*/
|
||||
SK_API void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
|
||||
SK_API void getResources(SkTDArray<SkPDFObject*>* resourceList,
|
||||
bool recursive) const;
|
||||
|
||||
/** Get the fonts used on this device.
|
||||
*/
|
||||
|
@ -40,9 +40,10 @@ public:
|
||||
* that the page is part of.
|
||||
* @param catalog The catalog to add page content objects to.
|
||||
* @param firstPage Indicate if this is the first page of a document.
|
||||
* @param resourceObjects The resource objects used on the page are added
|
||||
* to this array. This gives the caller a chance
|
||||
* to deduplicate resources across pages.
|
||||
* @param resourceObjects All the resource objects (recursively) used on
|
||||
* the page are added to this array. This gives
|
||||
* the caller a chance to deduplicate resources
|
||||
* across pages.
|
||||
*/
|
||||
void finalizePage(SkPDFCatalog* catalog, bool firstPage,
|
||||
SkTDArray<SkPDFObject*>* resourceObjects);
|
||||
|
@ -40,11 +40,11 @@ public:
|
||||
*/
|
||||
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
|
||||
|
||||
/** If this object explicitly depends on other objects, add them to the
|
||||
* end of the list. This only applies to higher level object, where
|
||||
* the depenency is explicit and introduced by the class. i.e. an
|
||||
* SkPDFImage added to an SkPDFDevice, but not an SkPDFObjRef added to
|
||||
* an SkPDFArray.
|
||||
/** For non-primitive objects (i.e. objects defined outside this file),
|
||||
* this method will add to resourceList any objects that this method
|
||||
* depends on. This operates recursively so if this object depends on
|
||||
* another object and that object depends on two more, all three objects
|
||||
* will be added.
|
||||
* @param resourceList The list to append dependant resources to.
|
||||
*/
|
||||
virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
|
||||
|
@ -1037,7 +1037,8 @@ SkPDFDict* SkPDFDevice::getResourceDict() {
|
||||
return fResourceDict.get();
|
||||
}
|
||||
|
||||
void SkPDFDevice::getResources(SkTDArray<SkPDFObject*>* resourceList) const {
|
||||
void SkPDFDevice::getResources(SkTDArray<SkPDFObject*>* resourceList,
|
||||
bool recursive) const {
|
||||
resourceList->setReserve(resourceList->count() +
|
||||
fGraphicStateResources.count() +
|
||||
fXObjectResources.count() +
|
||||
@ -1046,22 +1047,30 @@ void SkPDFDevice::getResources(SkTDArray<SkPDFObject*>* resourceList) const {
|
||||
for (int i = 0; i < fGraphicStateResources.count(); i++) {
|
||||
resourceList->push(fGraphicStateResources[i]);
|
||||
fGraphicStateResources[i]->ref();
|
||||
fGraphicStateResources[i]->getResources(resourceList);
|
||||
if (recursive) {
|
||||
fGraphicStateResources[i]->getResources(resourceList);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fXObjectResources.count(); i++) {
|
||||
resourceList->push(fXObjectResources[i]);
|
||||
fXObjectResources[i]->ref();
|
||||
fXObjectResources[i]->getResources(resourceList);
|
||||
if (recursive) {
|
||||
fXObjectResources[i]->getResources(resourceList);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fFontResources.count(); i++) {
|
||||
resourceList->push(fFontResources[i]);
|
||||
fFontResources[i]->ref();
|
||||
fFontResources[i]->getResources(resourceList);
|
||||
if (recursive) {
|
||||
fFontResources[i]->getResources(resourceList);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fShaderResources.count(); i++) {
|
||||
resourceList->push(fShaderResources[i]);
|
||||
fShaderResources[i]->ref();
|
||||
fShaderResources[i]->getResources(resourceList);
|
||||
if (recursive) {
|
||||
fShaderResources[i]->getResources(resourceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) {
|
||||
// We don't want to keep around device because we'd have two copies
|
||||
// of content, so reference or copy everything we need (content and
|
||||
// resources).
|
||||
device->getResources(&fResources);
|
||||
device->getResources(&fResources, false);
|
||||
|
||||
SkRefPtr<SkStream> content = device->content();
|
||||
content->unref(); // SkRefPtr and content() both took a reference.
|
||||
|
@ -32,7 +32,7 @@ void SkPDFPage::finalizePage(SkPDFCatalog* catalog, bool firstPage,
|
||||
insert("Contents", new SkPDFObjRef(fContentStream.get()))->unref();
|
||||
}
|
||||
catalog->addObject(fContentStream.get(), firstPage);
|
||||
fDevice->getResources(resourceObjects);
|
||||
fDevice->getResources(resourceObjects, true);
|
||||
}
|
||||
|
||||
off_t SkPDFPage::getPageSize(SkPDFCatalog* catalog, off_t fileOffset) {
|
||||
|
@ -693,7 +693,7 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
|
||||
// Put the canvas into the pattern stream (fContent).
|
||||
SkRefPtr<SkStream> content = pattern.content();
|
||||
content->unref(); // SkRefPtr and content() both took a reference.
|
||||
pattern.getResources(&fResources);
|
||||
pattern.getResources(&fResources, false);
|
||||
|
||||
setData(content.get());
|
||||
insertName("Type", "Pattern");
|
||||
|
Loading…
Reference in New Issue
Block a user