SurfaceTexture: fix a getTransformMatrix crash.

This change moves the computation of the transform matrix out of
getTransformMatrix and instead performs the computation when
updateTexImage gets called.  This is needed in order for
getTransformMatrix to succeed even if the buffers have been freed (e.g.
by changing the buffer count) because the computation depends upon the
properties of the current GraphicBuffer.

Change-Id: Ied541ab8747b7ad604f862717135f9a16a816be9
Bug: 4490420
This commit is contained in:
Jamie Gennis 2011-06-12 17:03:06 -07:00
parent 9797ca4634
commit 736aa9573b
2 changed files with 19 additions and 2 deletions

View File

@ -188,6 +188,11 @@ private:
status_t setBufferCountServerLocked(int bufferCount);
// computeCurrentTransformMatrix computes the transform matrix for the
// current texture. It uses mCurrentTransform and the current GraphicBuffer
// to compute this matrix and stores it in mCurrentTransformMatrix.
void computeCurrentTransformMatrix();
enum { INVALID_BUFFER_SLOT = -1 };
struct BufferSlot {
@ -322,6 +327,11 @@ private:
// gets set to mLastQueuedTransform each time updateTexImage is called.
uint32_t mCurrentTransform;
// mCurrentTransformMatrix is the transform matrix for the current texture.
// It gets computed by computeTransformMatrix each time updateTexImage is
// called.
float mCurrentTransformMatrix[16];
// mCurrentTimestamp is the timestamp for the current texture. It
// gets set to mLastQueuedTimestamp each time updateTexImage is called.
int64_t mCurrentTimestamp;
@ -362,6 +372,7 @@ private:
// variables of SurfaceTexture objects. It must be locked whenever the
// member variables are accessed.
mutable Mutex mMutex;
};
// ----------------------------------------------------------------------------

View File

@ -96,6 +96,7 @@ SurfaceTexture::SurfaceTexture(GLuint tex) :
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
mNextCrop.makeInvalid();
memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix));
}
SurfaceTexture::~SurfaceTexture() {
@ -547,6 +548,7 @@ status_t SurfaceTexture::updateTexImage() {
mCurrentCrop = mSlots[buf].mCrop;
mCurrentTransform = mSlots[buf].mTransform;
mCurrentTimestamp = mSlots[buf].mTimestamp;
computeCurrentTransformMatrix();
mDequeueCondition.signal();
} else {
// We always bind the texture even if we don't update its contents.
@ -596,8 +598,12 @@ GLenum SurfaceTexture::getCurrentTextureTarget() const {
}
void SurfaceTexture::getTransformMatrix(float mtx[16]) {
LOGV("SurfaceTexture::getTransformMatrix");
Mutex::Autolock lock(mMutex);
memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
}
void SurfaceTexture::computeCurrentTransformMatrix() {
LOGV("SurfaceTexture::computeCurrentTransformMatrix");
float xform[16];
for (int i = 0; i < 16; i++) {
@ -684,7 +690,7 @@ void SurfaceTexture::getTransformMatrix(float mtx[16]) {
// coordinate of 0, so SurfaceTexture must behave the same way. We don't
// want to expose this to applications, however, so we must add an
// additional vertical flip to the transform after all the other transforms.
mtxMul(mtx, mtxFlipV, mtxBeforeFlipV);
mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
}
nsecs_t SurfaceTexture::getTimestamp() {