am 2c8207e9
: add the ability to reject buffers in SurfaceTexture::updateTexImage
* commit '2c8207e9627fe6c7a90e31fae8d71ae49df56845': add the ability to reject buffers in SurfaceTexture::updateTexImage
This commit is contained in:
commit
584fcb3218
@ -236,6 +236,19 @@ protected:
|
|||||||
static bool isExternalFormat(uint32_t format);
|
static bool isExternalFormat(uint32_t format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// this version of updateTexImage() takes a functor used to reject or not
|
||||||
|
// the newly acquired buffer.
|
||||||
|
// this API is TEMPORARY and intended to be used by SurfaceFlinger only,
|
||||||
|
// which is why class Layer is made a friend of SurfaceTexture below.
|
||||||
|
class BufferRejecter {
|
||||||
|
friend class SurfaceTexture;
|
||||||
|
virtual bool reject(const sp<GraphicBuffer>& buf,
|
||||||
|
const BufferQueue::BufferItem& item) = 0;
|
||||||
|
protected:
|
||||||
|
virtual ~BufferRejecter() { }
|
||||||
|
};
|
||||||
|
friend class Layer;
|
||||||
|
status_t updateTexImage(BufferRejecter* rejecter);
|
||||||
|
|
||||||
// createImage creates a new EGLImage from a GraphicBuffer.
|
// createImage creates a new EGLImage from a GraphicBuffer.
|
||||||
EGLImageKHR createImage(EGLDisplay dpy,
|
EGLImageKHR createImage(EGLDisplay dpy,
|
||||||
|
@ -176,6 +176,10 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t SurfaceTexture::updateTexImage() {
|
status_t SurfaceTexture::updateTexImage() {
|
||||||
|
return SurfaceTexture::updateTexImage(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
ST_LOGV("updateTexImage");
|
ST_LOGV("updateTexImage");
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
@ -228,6 +232,16 @@ status_t SurfaceTexture::updateTexImage() {
|
|||||||
mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
|
mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we call the rejecter here, in case the caller has a reason to
|
||||||
|
// not accept this buffer. this is used by SurfaceFlinger to
|
||||||
|
// reject buffers which have the wrong size
|
||||||
|
if (rejecter && rejecter->reject(mEGLSlots[buf].mGraphicBuffer, item)) {
|
||||||
|
mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence);
|
||||||
|
mEGLSlots[buf].mFence = EGL_NO_SYNC_KHR;
|
||||||
|
glBindTexture(mTexTarget, mTexName);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the GL texture object. We may have to do this even when
|
// Update the GL texture object. We may have to do this even when
|
||||||
// item.mGraphicBuffer == NULL, if we destroyed the EGLImage when
|
// item.mGraphicBuffer == NULL, if we destroyed the EGLImage when
|
||||||
// detaching from a context but the buffer has not been re-allocated.
|
// detaching from a context but the buffer has not been re-allocated.
|
||||||
|
@ -527,31 +527,34 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
mFlinger->signalLayerUpdate();
|
mFlinger->signalLayerUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
|
struct Reject : public SurfaceTexture::BufferRejecter {
|
||||||
// something happened!
|
Layer::State& front;
|
||||||
recomputeVisibleRegions = true;
|
Layer::State& current;
|
||||||
return;
|
bool& recomputeVisibleRegions;
|
||||||
|
Reject(Layer::State& front, Layer::State& current,
|
||||||
|
bool& recomputeVisibleRegions)
|
||||||
|
: front(front), current(current),
|
||||||
|
recomputeVisibleRegions(recomputeVisibleRegions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the active buffer
|
virtual bool reject(const sp<GraphicBuffer>& buf,
|
||||||
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
|
const BufferQueue::BufferItem& item) {
|
||||||
|
if (buf == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t bufWidth = mActiveBuffer->getWidth();
|
uint32_t bufWidth = buf->getWidth();
|
||||||
uint32_t bufHeight = mActiveBuffer->getHeight();
|
uint32_t bufHeight = buf->getHeight();
|
||||||
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
|
|
||||||
const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
|
|
||||||
|
|
||||||
// check that we received a buffer of the right size
|
// check that we received a buffer of the right size
|
||||||
// (Take the buffer's orientation into account)
|
// (Take the buffer's orientation into account)
|
||||||
if (mCurrentTransform & Transform::ROT_90) {
|
if (item.mTransform & Transform::ROT_90) {
|
||||||
swap(bufWidth, bufHeight);
|
swap(bufWidth, bufHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the layer size if needed
|
|
||||||
const Layer::State& front(drawingState());
|
|
||||||
|
|
||||||
|
bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
|
||||||
if (front.active != front.requested) {
|
if (front.active != front.requested) {
|
||||||
bool isFixedSize = scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
|
|
||||||
|
|
||||||
if (isFixedSize ||
|
if (isFixedSize ||
|
||||||
(bufWidth == front.requested.w &&
|
(bufWidth == front.requested.w &&
|
||||||
@ -560,8 +563,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
// Here we pretend the transaction happened by updating the
|
// Here we pretend the transaction happened by updating the
|
||||||
// current and drawing states. Drawing state is only accessed
|
// current and drawing states. Drawing state is only accessed
|
||||||
// in this thread, no need to have it locked
|
// in this thread, no need to have it locked
|
||||||
Layer::State& editFront(mDrawingState);
|
front.active = front.requested;
|
||||||
editFront.active = front.requested;
|
|
||||||
|
|
||||||
// We also need to update the current state so that
|
// We also need to update the current state so that
|
||||||
// we don't end-up overwriting the drawing state with
|
// we don't end-up overwriting the drawing state with
|
||||||
@ -569,8 +571,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
//
|
//
|
||||||
// NOTE: We don't need to hold the transaction lock here
|
// NOTE: We don't need to hold the transaction lock here
|
||||||
// because State::active is only accessed from this thread.
|
// because State::active is only accessed from this thread.
|
||||||
Layer::State& editCurrent(currentState());
|
current.active = front.active;
|
||||||
editCurrent.active = front.active;
|
|
||||||
|
|
||||||
// recompute visible region
|
// recompute visible region
|
||||||
recomputeVisibleRegions = true;
|
recomputeVisibleRegions = true;
|
||||||
@ -580,7 +581,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
"lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
|
"lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
|
||||||
" drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
|
" drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
|
||||||
" requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
|
" requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
|
||||||
this, bufWidth, bufHeight, transform, scalingMode,
|
this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
|
||||||
front.active.w, front.active.h,
|
front.active.w, front.active.h,
|
||||||
front.active.crop.left,
|
front.active.crop.left,
|
||||||
front.active.crop.top,
|
front.active.crop.top,
|
||||||
@ -597,16 +598,42 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
front.requested.crop.getHeight());
|
front.requested.crop.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
mFrameLatencyNeeded = true;
|
if (!isFixedSize) {
|
||||||
|
if (front.active.w != bufWidth ||
|
||||||
|
front.active.h != bufHeight) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
|
||||||
|
|
||||||
|
if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
|
||||||
|
// something happened!
|
||||||
|
recomputeVisibleRegions = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update the active buffer
|
||||||
|
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
|
||||||
|
|
||||||
|
mFrameLatencyNeeded = true;
|
||||||
if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
|
if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
|
||||||
// the first time we receive a buffer, we need to trigger a
|
// the first time we receive a buffer, we need to trigger a
|
||||||
// geometry invalidation.
|
// geometry invalidation.
|
||||||
mFlinger->invalidateHwcGeometry();
|
mFlinger->invalidateHwcGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t bufWidth = mActiveBuffer->getWidth();
|
||||||
|
uint32_t bufHeight = mActiveBuffer->getHeight();
|
||||||
|
|
||||||
Rect crop(mSurfaceTexture->getCurrentCrop());
|
Rect crop(mSurfaceTexture->getCurrentCrop());
|
||||||
|
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
|
||||||
|
const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
|
||||||
if ((crop != mCurrentCrop) ||
|
if ((crop != mCurrentCrop) ||
|
||||||
(transform != mCurrentTransform) ||
|
(transform != mCurrentTransform) ||
|
||||||
(scalingMode != mCurrentScalingMode))
|
(scalingMode != mCurrentScalingMode))
|
||||||
@ -630,6 +657,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: mPostedDirtyRegion = dirty & bounds
|
// FIXME: mPostedDirtyRegion = dirty & bounds
|
||||||
|
const Layer::State& front(drawingState());
|
||||||
mPostedDirtyRegion.set(front.active.w, front.active.h);
|
mPostedDirtyRegion.set(front.active.w, front.active.h);
|
||||||
|
|
||||||
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
Loading…
Reference in New Issue
Block a user