Merge change 22011 into eclair
* changes: fix [2063336] Surface.lockSurface throws IllegalArgumentException when out of memory
This commit is contained in:
@@ -246,7 +246,7 @@ public class Surface implements Parcelable {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the display metrics used to provide canva's width/height in comaptibility mode.
|
* Sets the display metrics used to provide canva's width/height in compatibility mode.
|
||||||
*/
|
*/
|
||||||
void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
|
void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
|
||||||
mCompatibleDisplayMetrics = metrics;
|
mCompatibleDisplayMetrics = metrics;
|
||||||
@@ -275,7 +275,8 @@ public class Surface implements Parcelable {
|
|||||||
public native void clear();
|
public native void clear();
|
||||||
|
|
||||||
/** draw into a surface */
|
/** draw into a surface */
|
||||||
public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException {
|
public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException
|
||||||
|
{
|
||||||
/* the dirty rectangle may be expanded to the surface's size, if
|
/* the dirty rectangle may be expanded to the surface's size, if
|
||||||
* for instance it has been resized or if the bits were lost, since
|
* for instance it has been resized or if the bits were lost, since
|
||||||
* the last call.
|
* the last call.
|
||||||
|
|||||||
@@ -97,11 +97,9 @@ status_t Buffer::initSize(uint32_t w, uint32_t h, uint32_t reqUsage)
|
|||||||
err = allocator.alloc(w, h, format, usage, &handle, &stride);
|
err = allocator.alloc(w, h, format, usage, &handle, &stride);
|
||||||
|
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
if (err == NO_ERROR) {
|
width = w;
|
||||||
width = w;
|
height = h;
|
||||||
height = h;
|
mVStride = 0;
|
||||||
mVStride = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -64,11 +64,16 @@ SurfaceBuffer::SurfaceBuffer(const Parcel& data)
|
|||||||
{
|
{
|
||||||
// we own the handle in this case
|
// we own the handle in this case
|
||||||
width = data.readInt32();
|
width = data.readInt32();
|
||||||
height = data.readInt32();
|
if (width < 0) {
|
||||||
stride = data.readInt32();
|
width = height = stride = format = usage = 0;
|
||||||
format = data.readInt32();
|
handle = 0;
|
||||||
usage = data.readInt32();
|
} else {
|
||||||
handle = data.readNativeHandle();
|
height = data.readInt32();
|
||||||
|
stride = data.readInt32();
|
||||||
|
format = data.readInt32();
|
||||||
|
usage = data.readInt32();
|
||||||
|
handle = data.readNativeHandle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceBuffer::~SurfaceBuffer()
|
SurfaceBuffer::~SurfaceBuffer()
|
||||||
@@ -108,16 +113,25 @@ status_t SurfaceBuffer::unlock()
|
|||||||
status_t SurfaceBuffer::writeToParcel(Parcel* reply,
|
status_t SurfaceBuffer::writeToParcel(Parcel* reply,
|
||||||
android_native_buffer_t const* buffer)
|
android_native_buffer_t const* buffer)
|
||||||
{
|
{
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL)
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
|
|
||||||
|
if (buffer->width < 0 || buffer->height < 0)
|
||||||
|
return BAD_VALUE;
|
||||||
|
|
||||||
|
status_t err = NO_ERROR;
|
||||||
|
if (buffer->handle == NULL) {
|
||||||
|
// this buffer doesn't have a handle
|
||||||
|
reply->writeInt32(NO_MEMORY);
|
||||||
|
} else {
|
||||||
|
reply->writeInt32(buffer->width);
|
||||||
|
reply->writeInt32(buffer->height);
|
||||||
|
reply->writeInt32(buffer->stride);
|
||||||
|
reply->writeInt32(buffer->format);
|
||||||
|
reply->writeInt32(buffer->usage);
|
||||||
|
err = reply->writeNativeHandle(buffer->handle);
|
||||||
}
|
}
|
||||||
reply->writeInt32(buffer->width);
|
return err;
|
||||||
reply->writeInt32(buffer->height);
|
|
||||||
reply->writeInt32(buffer->stride);
|
|
||||||
reply->writeInt32(buffer->format);
|
|
||||||
reply->writeInt32(buffer->usage);
|
|
||||||
reply->writeNativeHandle(buffer->handle);
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
@@ -434,7 +448,7 @@ Surface::~Surface()
|
|||||||
// this is a client-side operation, the surface is destroyed, unmap
|
// this is a client-side operation, the surface is destroyed, unmap
|
||||||
// its buffers in this process.
|
// its buffers in this process.
|
||||||
for (int i=0 ; i<2 ; i++) {
|
for (int i=0 ; i<2 ; i++) {
|
||||||
if (mBuffers[i] != 0) {
|
if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
|
||||||
getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
|
getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -590,17 +604,24 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer)
|
|||||||
if ((back->flags & surface_info_t::eNeedNewBuffer) || mUsageChanged) {
|
if ((back->flags & surface_info_t::eNeedNewBuffer) || mUsageChanged) {
|
||||||
mUsageChanged = false;
|
mUsageChanged = false;
|
||||||
err = getBufferLocked(backIdx, mUsage);
|
err = getBufferLocked(backIdx, mUsage);
|
||||||
|
if (err == NO_ERROR) {
|
||||||
|
// reset the width/height with the what we get from the buffer
|
||||||
|
const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
|
||||||
|
mWidth = uint32_t(backBuffer->width);
|
||||||
|
mHeight = uint32_t(backBuffer->height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
|
const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
|
||||||
// reset the width/height with the what we get from the buffer
|
if (backBuffer != 0) {
|
||||||
mWidth = uint32_t(backBuffer->width);
|
mDirtyRegion.set(backBuffer->width, backBuffer->height);
|
||||||
mHeight = uint32_t(backBuffer->height);
|
*buffer = backBuffer.get();
|
||||||
mDirtyRegion.set(backBuffer->width, backBuffer->height);
|
} else {
|
||||||
*buffer = backBuffer.get();
|
err = NO_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,7 +737,8 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
|
|||||||
} else {
|
} else {
|
||||||
newDirtyRegion.andSelf(bounds);
|
newDirtyRegion.andSelf(bounds);
|
||||||
const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
|
const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
|
||||||
if (backBuffer->width == frontBuffer->width &&
|
if (frontBuffer !=0 &&
|
||||||
|
backBuffer->width == frontBuffer->width &&
|
||||||
backBuffer->height == frontBuffer->height &&
|
backBuffer->height == frontBuffer->height &&
|
||||||
!(lcblk->flags & eNoCopyBack))
|
!(lcblk->flags & eNoCopyBack))
|
||||||
{
|
{
|
||||||
@@ -788,18 +810,24 @@ status_t Surface::getBufferLocked(int index, int usage)
|
|||||||
if (s == 0) return NO_INIT;
|
if (s == 0) return NO_INIT;
|
||||||
|
|
||||||
status_t err = NO_MEMORY;
|
status_t err = NO_MEMORY;
|
||||||
|
|
||||||
|
// free the current buffer
|
||||||
|
sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
|
||||||
|
if (currentBuffer != 0) {
|
||||||
|
getBufferMapper().unregisterBuffer(currentBuffer->handle);
|
||||||
|
currentBuffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
sp<SurfaceBuffer> buffer = s->getBuffer(usage);
|
sp<SurfaceBuffer> buffer = s->getBuffer(usage);
|
||||||
LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
|
LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
|
||||||
if (buffer != 0) {
|
if (buffer != 0) { // this should never happen by construction
|
||||||
sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
|
if (buffer->handle != NULL) {
|
||||||
if (currentBuffer != 0) {
|
err = getBufferMapper().registerBuffer(buffer->handle);
|
||||||
getBufferMapper().unregisterBuffer(currentBuffer->handle);
|
LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
|
||||||
currentBuffer.clear();
|
err, strerror(-err));
|
||||||
}
|
if (err == NO_ERROR) {
|
||||||
err = getBufferMapper().registerBuffer(buffer->handle);
|
currentBuffer = buffer;
|
||||||
LOGW_IF(err, "registerBuffer(...) failed %d (%s)", err, strerror(-err));
|
}
|
||||||
if (err == NO_ERROR) {
|
|
||||||
currentBuffer = buffer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
Reference in New Issue
Block a user