void BufferQueueDump::onAcquireBuffer(const int slot, const sp<GraphicBuffer>& buffer, const sp<Fence>& fence) { if (buffer == NULL) { ST_LOGW("onAcquireBuffer: The GraphicBuffer of slot%d is NULL, ignore it", slot); return; } // check this slot in vector for (uint32_t i = mAcquiredBufs.size(); i > 0; i--) { uint32_t index = i - 1; if ((mAcquiredBufs[index]->mSlot == slot) || (mAcquiredBufs[index]->mSlot == BufferQueue::INVALID_BUFFER_SLOT)) { // remove the items which are same with slot id or freed mAcquiredBufs.removeAt(index); ST_LOGD("onAcquireBuffer: find slot%d has been in acquired buffer[%u], remove it", slot, index); } } // push new buffer into vector sp<AcquiredBuffer> acquiredBuffer = new AcquiredBuffer(slot, buffer, fence, systemTime()); if (acquiredBuffer == NULL) { XLOGE("[%s] alloc AcquiredBuffer failed", __func__); return; } mAcquiredBufs.push_back(acquiredBuffer); }
void SurfaceTexture::setFilteringEnabled(bool enabled) { Mutex::Autolock lock(mMutex); if (mAbandoned) { ST_LOGE("setFilteringEnabled: SurfaceTexture is abandoned!"); return; } bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; if (needsRecompute && mCurrentTextureBuf==NULL) { ST_LOGD("setFilteringEnabled called with mCurrentTextureBuf == NULL"); } if (needsRecompute && mCurrentTextureBuf != NULL) { computeCurrentTransformMatrixLocked(); } }
void BufferQueueDump::dumpBuffer() const { char value[PROPERTY_VALUE_MAX]; property_get(PROP_DUMP_NAME, value, DEFAULT_DUMP_NAME); if (strstr(value, PREFIX_NODUMP) == value) { // find prefix for no dump return; } if (!((!strcmp(value, STR_DUMPALL)) || (-1 != mName.find(value)))) { // no dump for me return; } // at first, dump backup buffer if needed if (mBackupBuf.getSize() > 0) { // dump all backup buffer mBackupBuf.dump(); } String8 name; String8 prefix; getDumpFileName(name, mName); uint32_t offset = mBackupBuf.getValidSize(); // dump acquired buffers for (uint32_t i = 0; i < mAcquiredBufs.size(); i++) { if (mAcquiredBufs[i]->mGraphicBuffer != NULL) { prefix = String8::format("%s_%u_ts%lldms", name.string(), offset + i, ns2ms(mAcquiredBufs[i]->mTimeStamp)); if (mAcquiredBufs[i]->mFence != NULL) mAcquiredBufs[i]->mFence->waitForever("BufferQueue::Dump::dumpBuffer"); GraphicBufferExtra::dump(mAcquiredBufs[i]->mGraphicBuffer, prefix.string(), DUMP_FILE_PATH); ST_LOGD("dumpBuffer: dump acquired buffer %u", i); } } }
void SurfaceTexture::computeCurrentTransformMatrixLocked() { ST_LOGV("computeCurrentTransformMatrixLocked"); float xform[16]; for (int i = 0; i < 16; i++) { xform[i] = mtxIdentity[i]; } if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { float result[16]; mtxMul(result, xform, mtxFlipH); for (int i = 0; i < 16; i++) { xform[i] = result[i]; } } if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { float result[16]; mtxMul(result, xform, mtxFlipV); for (int i = 0; i < 16; i++) { xform[i] = result[i]; } } if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { float result[16]; mtxMul(result, xform, mtxRot90); for (int i = 0; i < 16; i++) { xform[i] = result[i]; } } sp<GraphicBuffer>& buf(mCurrentTextureBuf); if (buf == NULL) { ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL"); } Rect cropRect = mCurrentCrop; float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; float bufferWidth = buf->getWidth(); float bufferHeight = buf->getHeight(); if (!cropRect.isEmpty()) { float shrinkAmount = 0.0f; if (mFilteringEnabled) { // In order to prevent bilinear sampling beyond the edge of the // crop rectangle we may need to shrink it by 2 texels in each // dimension. Normally this would just need to take 1/2 a texel // off each end, but because the chroma channels of YUV420 images // are subsampled we may need to shrink the crop region by a whole // texel on each side. switch (buf->getPixelFormat()) { case PIXEL_FORMAT_RGBA_8888: case PIXEL_FORMAT_RGBX_8888: case PIXEL_FORMAT_RGB_888: case PIXEL_FORMAT_RGB_565: case PIXEL_FORMAT_BGRA_8888: case PIXEL_FORMAT_RGBA_5551: case PIXEL_FORMAT_RGBA_4444: // We know there's no subsampling of any channels, so we // only need to shrink by a half a pixel. shrinkAmount = 0.5; break; default: // If we don't recognize the format, we must assume the // worst case (that we care about), which is YUV420. shrinkAmount = 1.0; break; } } // Only shrink the dimensions that are not the size of the buffer. if (cropRect.width() < bufferWidth) { tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / bufferWidth; } if (cropRect.height() < bufferHeight) { ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / bufferHeight; sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / bufferHeight; } } float crop[16] = { sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1, }; float mtxBeforeFlipV[16]; mtxMul(mtxBeforeFlipV, crop, xform); // SurfaceFlinger expects the top of its window textures to be at a Y // 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(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); }