Beispiel #1
0
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();
    }
}
Beispiel #3
0
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);
}