Bug 517119 - Preallocate image source data buffer based on Content-Length.r=jrmuizel,sr=vlad.

This commit is contained in:
Bobby Holley 2010-06-25 11:21:40 -07:00
parent 2bf11cef6f
commit fa74df73e2
3 changed files with 41 additions and 1 deletions

View File

@ -71,7 +71,7 @@ native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, uuid(74c63935-b54f-43a4-9449-2e9c815e3bef)]
[scriptable, uuid(e80ec20d-8e9c-405f-a673-cea00aa95b4d)]
interface imgIContainer : nsISupports
{
/**
@ -359,4 +359,16 @@ interface imgIContainer : nsISupports
/* Called for multipart images when there's a new source image to add. */
[noscript] void newSourceData();
/**
* A hint of the number of bytes of source data that the image contains. If
* called early on, this can help reduce copying and reallocations by
* appropriately preallocating the source data buffer.
*
* We take this approach rather than having the source data management code do
* something more complicated (like chunklisting) because HTTP is by far the
* dominant source of images, and the Content-Length header is quite reliable.
* Thus, pre-allocation simplifies code and reduces the total number of
* allocations.
*/
void setSourceSizeHint(in unsigned long sizeHint);
};

View File

@ -1396,6 +1396,15 @@ NS_IMETHODIMP imgContainer::NewSourceData()
return NS_OK;
}
//******************************************************************************
/* void setSourceSizeHint(in unsigned long sizeHint); */
NS_IMETHODIMP imgContainer::SetSourceSizeHint(PRUint32 sizeHint)
{
if (sizeHint && StoringSourceData())
mSourceData.SetCapacity(sizeHint);
return NS_OK;
}
//******************************************************************************
/* void notify(in nsITimer timer); */
NS_IMETHODIMP imgContainer::Notify(nsITimer *timer)

View File

@ -1173,6 +1173,25 @@ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctx
return NS_BINDING_ABORTED;
}
/* Use content-length as a size hint for http channels. */
if (httpChannel) {
nsCAutoString contentLength;
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
contentLength);
if (NS_SUCCEEDED(rv)) {
PRInt32 len = contentLength.ToInteger(&rv);
// Pass anything usable on so that the imgContainer can preallocate its
// source buffer
if (len > 0) {
PRUint32 sizeHint = (PRUint32) len;
sizeHint = PR_MIN(sizeHint, 20000000); /* Bound by something reasonable */
mImage->SetSourceSizeHint(sizeHint);
}
}
}
// If we were waiting on the image to do something, now's our chance.
if (mDecodeRequested) {
mImage->RequestDecode();