int PreviewRenderer::init() {
    int err = 0;
    ANativeWindow* anw = mSurface.get();

    err = native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
    if (err) goto fail;

    err = native_window_set_usage(
            anw, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN);
    if (err) goto fail;

    err = native_window_set_buffer_count(anw, 3);
    if (err) goto fail;

    err = native_window_set_scaling_mode(
            anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    if (err) goto fail;

    err = native_window_set_buffers_geometry(
            anw, mWidth, mHeight, HAL_PIXEL_FORMAT_YV12);
    if (err) goto fail;

    err = native_window_set_buffers_transform(anw, 0);
    if (err) goto fail;

fail:
    return err;
}
Exemple #2
0
int IOMXHWBuffer_Setup( void *window, int w, int h, int hal_format, int hw_usage )
{
    ANativeWindow *anw = (ANativeWindow *)window;
    int usage = 0;
    status_t err;

    CHECK_ANW();

    LOGD( "IOMXHWBuffer_setup: %p, %d, %d, %X, %X\n",
          anw, w, h, hal_format, hw_usage );

    usage |= hw_usage | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
#if ANDROID_API >= 11
    usage |= GRALLOC_USAGE_EXTERNAL_DISP;
#endif

    err = native_window_set_usage( anw, usage );
    CHECK_ERR();

#if ANDROID_API <= 13
    err = native_window_set_buffers_geometry( anw, w, h, hal_format );
    CHECK_ERR();
#else
    err = native_window_set_scaling_mode( anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW );
    CHECK_ERR();

    err = native_window_set_buffers_dimensions( anw, w, h );
    CHECK_ERR();

    err = native_window_set_buffers_format( anw, hal_format );
    CHECK_ERR();
#endif

    return 0;
}
Exemple #3
0
void TransferQueue::initGLResources(int width, int height)
{
    android::Mutex::Autolock lock(m_transferQueueItemLocks);
    if (!m_sharedSurfaceTextureId) {
        glGenTextures(1, &m_sharedSurfaceTextureId);
        sp<BufferQueue> bufferQueue(new BufferQueue(true));
        m_sharedSurfaceTexture =
#if GPU_UPLOAD_WITHOUT_DRAW
            new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
                                        GL_TEXTURE_2D, true, bufferQueue);
#else
            new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
                                        GL_TEXTURE_EXTERNAL_OES, true,
                                        bufferQueue);
#endif
        m_ANW = new android::SurfaceTextureClient(m_sharedSurfaceTexture);
        m_sharedSurfaceTexture->setSynchronousMode(true);

        int extraBuffersNeeded = 0;
        m_ANW->query(m_ANW.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
                     &extraBuffersNeeded);
        bufferQueue->setBufferCount(m_transferQueueSize + extraBuffersNeeded);

        int result = native_window_set_buffers_geometry(m_ANW.get(),
                width, height, HAL_PIXEL_FORMAT_RGBA_8888);
        GLUtils::checkSurfaceTextureError("native_window_set_buffers_geometry", result);
        result = native_window_set_usage(m_ANW.get(),
                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
        GLUtils::checkSurfaceTextureError("native_window_set_usage", result);
    }

    if (!m_fboID)
        glGenFramebuffers(1, &m_fboID);
}
Exemple #4
0
void TransferQueue::initSharedSurfaceTextures(int width, int height)
{
    if (!m_sharedSurfaceTextureId) {
        glGenTextures(1, &m_sharedSurfaceTextureId);
        m_sharedSurfaceTexture =
#if GPU_UPLOAD_WITHOUT_DRAW
            new android::SurfaceTexture(m_sharedSurfaceTextureId, true, GL_TEXTURE_2D);
#else
            new android::SurfaceTexture(m_sharedSurfaceTextureId);
#endif
        m_ANW = new android::SurfaceTextureClient(m_sharedSurfaceTexture);
        m_sharedSurfaceTexture->setSynchronousMode(true);
        m_sharedSurfaceTexture->setBufferCount(ST_BUFFER_NUMBER+1);

        int result = native_window_set_buffers_geometry(m_ANW.get(),
                width, height, HAL_PIXEL_FORMAT_RGBA_8888);
        GLUtils::checkSurfaceTextureError("native_window_set_buffers_geometry", result);
        result = native_window_set_usage(m_ANW.get(),
                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
        GLUtils::checkSurfaceTextureError("native_window_set_usage", result);
    }

    if (!m_fboID)
        glGenFramebuffers(1, &m_fboID);
}
 explicit TestWindowData(SkISize size) : mSize(size) {
     android::BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     mCpuConsumer = new android::CpuConsumer(mConsumer, 1);
     mCpuConsumer->setName(android::String8("TestWindowContext"));
     mCpuConsumer->setDefaultBufferSize(mSize.width(), mSize.height());
     mAndroidSurface = new android::Surface(mProducer);
     native_window_set_buffers_dimensions(mAndroidSurface.get(), mSize.width(), mSize.height());
     native_window_set_buffers_format(mAndroidSurface.get(), android::PIXEL_FORMAT_RGBA_8888);
     native_window_set_usage(mAndroidSurface.get(), GRALLOC_USAGE_SW_READ_OFTEN |
                                                            GRALLOC_USAGE_SW_WRITE_NEVER |
                                                            GRALLOC_USAGE_HW_RENDER);
     mRootNode.reset(new android::uirenderer::RenderNode());
     mRootNode->incStrong(nullptr);
     mRootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, mSize.width(),
                                                                mSize.height());
     mRootNode->mutateStagingProperties().setClipToBounds(false);
     mRootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::GENERIC);
     ContextFactory factory;
     mProxy.reset(new android::uirenderer::renderthread::RenderProxy(false, mRootNode.get(),
                                                                     &factory));
     mProxy->loadSystemProperties();
     mProxy->initialize(mAndroidSurface.get());
     float lightX = mSize.width() / 2.0f;
     android::uirenderer::Vector3 lightVector{lightX, -200.0f, 800.0f};
     mProxy->setup(800.0f, 255 * 0.075f, 255 * 0.15f);
     mProxy->setLightCenter(lightVector);
     mCanvas.reset(new android::uirenderer::RecordingCanvas(mSize.width(), mSize.height()));
 }
void NativeWindowRenderer::queueExternalBuffer(ANativeWindow* anw,
    MediaBuffer* buffer, int width, int height) {
    native_window_set_buffers_geometry(anw, width, height,
            HAL_PIXEL_FORMAT_YV12);
    native_window_set_usage(anw, GRALLOC_USAGE_SW_WRITE_OFTEN);

#ifdef QCOM_HARDWARE
    native_window_set_buffer_count(anw, 3);
#endif

    ANativeWindowBuffer* anb;
    anw->dequeueBuffer(anw, &anb);
    CHECK(anb != NULL);

    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    CHECK(NO_ERROR == anw->lockBuffer(anw, buf->getNativeBuffer()));

    // Copy the buffer
    uint8_t* img = NULL;
    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    copyI420Buffer(buffer, img, width, height, buf->getStride());

#if PREVIEW_DEBUG
    FILE *fp1 = fopen("/sdcard/pre_test_yuv.raw", "ab");
    if(fp1 == NULL)
        LOGE("Errors file can not be created");
    else {
        fwrite(img, buf->getWidth() * buf->getHeight()* 3/2, 1, fp1);
        fclose(fp1);
    }
#endif

    buf->unlock();
    CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer()));
}
// This test is intended to verify that proper synchronization is done when
// rendering into an FBO.
TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
    const int texWidth = 64;
    const int texHeight = 64;

    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));

    android_native_buffer_t* anb;
    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
            &anb));
    ASSERT_TRUE(anb != NULL);

    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));

    // Fill the buffer with green
    uint8_t* img = NULL;
    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
            0, 255);
    buf->unlock();
    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
            -1));

    ASSERT_EQ(NO_ERROR, mST->updateTexImage());

    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
    drawTexture();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    for (int i = 0; i < 4; i++) {
        SCOPED_TRACE(String8::format("frame %d", i).string());

        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
                &anb));
        ASSERT_TRUE(anb != NULL);

        buf = new GraphicBuffer(anb, false);

        // Fill the buffer with red
        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
                (void**)(&img)));
        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
                0, 255);
        ASSERT_EQ(NO_ERROR, buf->unlock());
        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
                buf->getNativeBuffer(), -1));

        ASSERT_EQ(NO_ERROR, mST->updateTexImage());

        drawTexture();

        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
    }

    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);

    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
}
CedarXSoftwareRenderer::CedarXSoftwareRenderer(
        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
    : mYUVMode(None),
      mNativeWindow(nativeWindow) {
    int32_t tmp;
    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;

    //CHECK(meta->findInt32(kKeyScreenID, &screenID));
    //CHECK(meta->findInt32(kKeyColorFormat, &halFormat));
    CHECK(meta->findInt32(kKeyWidth, &mWidth));
    CHECK(meta->findInt32(kKeyHeight, &mHeight));

    int32_t rotationDegrees;
    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
        rotationDegrees = 0;
    }

    int halFormat;
    size_t bufWidth, bufHeight;

    halFormat = HAL_PIXEL_FORMAT_YV12;
    bufWidth = mWidth;
    bufHeight = mHeight;

    CHECK(mNativeWindow != NULL);

    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));

    CHECK_EQ(0,
            native_window_set_scaling_mode(
            mNativeWindow.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    // Width must be multiple of 32???
    CHECK_EQ(0, native_window_set_buffers_geometry(
                mNativeWindow.get(),
                bufWidth,
                bufHeight,
                halFormat));

    uint32_t transform;
    switch (rotationDegrees) {
        case 0: transform = 0; break;
        case 90: transform = HAL_TRANSFORM_ROT_90; break;
        case 180: transform = HAL_TRANSFORM_ROT_180; break;
        case 270: transform = HAL_TRANSFORM_ROT_270; break;
        default: transform = 0; break;
    }

    if (transform) {
        CHECK_EQ(0, native_window_set_buffers_transform(
                    mNativeWindow.get(), transform));
    }
}
	FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
		: FrameBuffer(width, height, false, false),
		  nativeWindow(window), buffer(nullptr), gralloc(nullptr)
	{
		hw_module_t const* pModule;
		hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
		gralloc = reinterpret_cast<gralloc_module_t const*>(pModule);

		nativeWindow->common.incRef(&nativeWindow->common);
		native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
	}
// This test probably doesn't belong here.
TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
    sp<ANativeWindow> anw(mSurface);

    // Verify the screenshot works with no protected buffers.
    sp<CpuConsumer> consumer = new CpuConsumer(1);
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
            64, 64, 0, 0x7fffffff, true));

    // Set the PROTECTED usage bit and verify that the screenshot fails.  Note
    // that we need to dequeue a buffer in order for it to actually get
    // allocated in SurfaceFlinger.
    ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
            GRALLOC_USAGE_PROTECTED));
    ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
    ANativeWindowBuffer* buf = 0;

    status_t err = native_window_dequeue_buffer_and_wait(anw.get(), &buf);
    if (err) {
        // we could fail if GRALLOC_USAGE_PROTECTED is not supported.
        // that's okay as long as this is the reason for the failure.
        // try again without the GRALLOC_USAGE_PROTECTED bit.
        ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
                &buf));
        return;
    }
    ASSERT_EQ(NO_ERROR, anw->cancelBuffer(anw.get(), buf, -1));

    for (int i = 0; i < 4; i++) {
        // Loop to make sure SurfaceFlinger has retired a protected buffer.
        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
                &buf));
        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
    }
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
            64, 64, 0, 0x7fffffff, true));
}
static struct native_surface *
android_display_create_window_surface(struct native_display *ndpy,
                                      EGLNativeWindowType win,
                                      const struct native_config *nconf)
{
   struct android_display *adpy = android_display(ndpy);
   struct android_config *aconf = android_config(nconf);
   struct android_surface *asurf;
   enum pipe_format format;
   int val;

   if (win->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
      LOGE("invalid native window with magic 0x%x", win->common.magic);
      return NULL;
   }
   if (win->query(win, NATIVE_WINDOW_FORMAT, &val)) {
      LOGE("failed to query native window format");
      return NULL;
   }
   format = get_pipe_format(val);
   if (format != nconf->color_format) {
      LOGW("native window format 0x%x != config format 0x%x",
            format, nconf->color_format);
      if (!adpy->base.screen->is_format_supported(adpy->base.screen,
               format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) {
         LOGE("and the native window cannot be used as a render target");
         return NULL;
      }
   }

   asurf = CALLOC_STRUCT(android_surface);
   if (!asurf)
      return NULL;

   asurf->adpy = adpy;
   asurf->win = win;
   asurf->win->common.incRef(&asurf->win->common);

   /* request buffers that are for CPU access */
   if (!adpy->use_drm) {
      native_window_set_usage(asurf->win,
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
   }

   asurf->base.destroy = android_surface_destroy;
   asurf->base.present = android_surface_present;
   asurf->base.validate = android_surface_validate;
   asurf->base.wait = android_surface_wait;

   return &asurf->base;
}
Exemple #12
0
bool EncodeInputSurface::init(const char* inputFileName, uint32_t fourcc, int width, int height)
{
    m_width = width;
    m_height = height;

    int surfaceWidth = width;
    int surfaceHeight = height;
    static sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    //create surface
    static sp<SurfaceControl> surfaceCtl = client->createSurface(String8("testsurface"),
        surfaceWidth, surfaceHeight, HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, 0);
    DEBUG("create surface with size %dx%d, format: 0x%x", surfaceWidth, surfaceHeight, HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL);

    // configure surface
    SurfaceComposerClient::openGlobalTransaction();
    surfaceCtl->setLayer(100000);
    surfaceCtl->setPosition(100, 100);
    surfaceCtl->setSize(surfaceWidth, surfaceHeight);
    SurfaceComposerClient::closeGlobalTransaction();

    m_surface = surfaceCtl->getSurface();
    mNativeWindow = m_surface;

    int bufWidth = width;
    int bufHeight = height;
    int ret;

    INFO("set buffers geometry %dx%d\n", width, height);
    ret = native_window_set_buffers_dimensions(GET_ANATIVEWINDOW(mNativeWindow), width, height);
    CHECK_RET(ret, "native_window_set_buffers_dimensions");

    uint32_t format = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL;
    INFO("set buffers format %x\n", format);
    ret = native_window_set_buffers_format(GET_ANATIVEWINDOW(mNativeWindow), format);
    CHECK_RET(ret, "native_window_set_buffers_format");

    INFO("set buffer usage\n");
    ret = native_window_set_usage(GET_ANATIVEWINDOW(mNativeWindow),
        GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_TEXTURE);
    CHECK_RET(ret, "native_window_set_usage");

    INFO("set buffer count %d\n", m_bufferCount);
    ret = native_window_set_buffer_count(GET_ANATIVEWINDOW(mNativeWindow), m_bufferCount);
    CHECK_RET(ret, "native_window_set_buffer_count");

    prepareInputBuffer();
    return true;
}
status_t BufferProducerThread::readyToRun() {
    sp<ANativeWindow> anw(mSurface);
    status_t err = native_window_set_usage(anw.get(), mStream.buffer_producer.usage);
    if (err != NO_ERROR) {
        return err;
    }
    err = native_window_set_buffers_dimensions(
              anw.get(), mStream.buffer_producer.width, mStream.buffer_producer.height);
    if (err != NO_ERROR) {
        return err;
    }
    err = native_window_set_buffers_format(anw.get(), mStream.buffer_producer.format);
    if (err != NO_ERROR) {
        return err;
    }
    return NO_ERROR;
}
void NativeWindowRenderer::queueExternalBuffer(ANativeWindow* anw,
    MediaBuffer* buffer, int width, int height) {
    native_window_set_buffers_geometry(anw, width, height,
            HAL_PIXEL_FORMAT_YV12);
    native_window_set_usage(anw, GRALLOC_USAGE_SW_WRITE_OFTEN);

    ANativeWindowBuffer* anb;
    CHECK(NO_ERROR == native_window_dequeue_buffer_and_wait(anw, &anb));
    CHECK(anb != NULL);

    // Copy the buffer
    uint8_t* img = NULL;
    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    copyI420Buffer(buffer, img, width, height, buf->getStride());
    buf->unlock();
    CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer(), -1));
}
Exemple #15
0
bool createNativeWindow(__u32 pixelformat)
{
    mClient = new SurfaceComposerClient();
    mSurfaceCtl = mClient->createSurface(String8("testsurface"),
                                      800, 600, pixelformat, 0);

    // configure surface
    SurfaceComposerClient::openGlobalTransaction();
    mSurfaceCtl->setLayer(100000);
    mSurfaceCtl->setPosition(100, 100);
    mSurfaceCtl->setSize(800, 600);
    SurfaceComposerClient::closeGlobalTransaction();

    mSurface = mSurfaceCtl->getSurface();
    mNativeWindow = mSurface;

    int bufWidth = 640;
    int bufHeight = 480;
    CHECK_EQ(0,
             native_window_set_usage(
             mNativeWindow.get(),
             GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
             | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));

    CHECK_EQ(0,
             native_window_set_scaling_mode(
             mNativeWindow.get(),
             NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    CHECK_EQ(0, native_window_set_buffers_geometry(
                mNativeWindow.get(),
                bufWidth,
                bufHeight,
                pixelformat));

    return true;
}
Exemple #16
0
SoftwareRenderer::SoftwareRenderer(
        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
    : mConverter(NULL),
      mYUVMode(None),
      mNativeWindow(nativeWindow) {
    int32_t tmp;
    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;

    CHECK(meta->findInt32(kKeyWidth, &mWidth));
    CHECK(meta->findInt32(kKeyHeight, &mHeight));

    if (!meta->findRect(
                kKeyCropRect,
                &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) {
        mCropLeft = mCropTop = 0;
        mCropRight = mWidth - 1;
        mCropBottom = mHeight - 1;
    }

    mCropWidth = mCropRight - mCropLeft + 1;
    mCropHeight = mCropBottom - mCropTop + 1;

    int32_t rotationDegrees;
    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
        rotationDegrees = 0;
    }

    int halFormat;
    size_t bufWidth, bufHeight;

    switch (mColorFormat) {
        case OMX_COLOR_FormatYUV420Planar:
        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
        {
            halFormat = HAL_PIXEL_FORMAT_YV12;
            bufWidth = (mCropWidth + 1) & ~1;
            bufHeight = (mCropHeight + 1) & ~1;

            if (ALIGN(bufWidth, 16) / 2 == ALIGN(bufWidth / 2, 16))
            {
                break;
            }
        }

        default:
            halFormat = HAL_PIXEL_FORMAT_RGB_565;
            bufWidth = mCropWidth;
            bufHeight = mCropHeight;

            mConverter = new ColorConverter(
                    mColorFormat, OMX_COLOR_Format16bitRGB565);
            CHECK(mConverter->isValid());
            break;
    }

    CHECK(mNativeWindow != NULL);
    CHECK(mCropWidth > 0);
    CHECK(mCropHeight > 0);
    CHECK(mConverter == NULL || mConverter->isValid());

    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));

    CHECK_EQ(0,
            native_window_set_scaling_mode(
            mNativeWindow.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    // Width must be multiple of 32???
    CHECK_EQ(0, native_window_set_buffers_geometry(
                mNativeWindow.get(),
                bufWidth,
                bufHeight,
                halFormat));

    uint32_t transform;
    switch (rotationDegrees) {
        case 0: transform = 0; break;
        case 90: transform = HAL_TRANSFORM_ROT_90; break;
        case 180: transform = HAL_TRANSFORM_ROT_180; break;
        case 270: transform = HAL_TRANSFORM_ROT_270; break;
        default: transform = 0; break;
    }

    if (transform) {
        CHECK_EQ(0, native_window_set_buffers_transform(
                    mNativeWindow.get(), transform));
    }
}
status_t StreamAdapter::connectToDevice(camera2_device_t *d,
        uint32_t width, uint32_t height, int format) {
    if (mState != UNINITIALIZED) return INVALID_OPERATION;
    if (d == NULL) {
        ALOGE("%s: Null device passed to stream adapter", __FUNCTION__);
        return BAD_VALUE;
    }

    status_t res;

    mWidth = width;
    mHeight = height;
    mFormat = format;

    // Allocate device-side stream interface

    uint32_t id;
    uint32_t formatActual; // ignored
    uint32_t usage;
    uint32_t maxBuffers = 2;
    res = d->ops->allocate_stream(d,
            mWidth, mHeight, mFormat, getStreamOps(),
            &id, &formatActual, &usage, &maxBuffers);
    if (res != OK) {
        ALOGE("%s: Device stream allocation failed: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        mState = UNINITIALIZED;
        return res;
    }
    mDevice = d;

    mId = id;
    mUsage = usage;
    mMaxProducerBuffers = maxBuffers;

    // Configure consumer-side ANativeWindow interface

    res = native_window_api_connect(mConsumerInterface.get(),
            NATIVE_WINDOW_API_CAMERA);
    if (res != OK) {
        ALOGE("%s: Unable to connect to native window for stream %d",
                __FUNCTION__, mId);
        mState = ALLOCATED;
        return res;
    }

    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
    if (res != OK) {
        ALOGE("%s: Unable to configure usage %08x for stream %d",
                __FUNCTION__, mUsage, mId);
        mState = CONNECTED;
        return res;
    }

    res = native_window_set_buffers_geometry(mConsumerInterface.get(),
            mWidth, mHeight, mFormat);
    if (res != OK) {
        ALOGE("%s: Unable to configure buffer geometry"
                " %d x %d, format 0x%x for stream %d",
                __FUNCTION__, mWidth, mHeight, mFormat, mId);
        mState = CONNECTED;
        return res;
    }

    int maxConsumerBuffers;
    res = mConsumerInterface->query(mConsumerInterface.get(),
            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
    if (res != OK) {
        ALOGE("%s: Unable to query consumer undequeued"
                " buffer count for stream %d", __FUNCTION__, mId);
        mState = CONNECTED;
        return res;
    }
    mMaxConsumerBuffers = maxConsumerBuffers;

    ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__,
            mMaxProducerBuffers, mMaxConsumerBuffers);

    int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;

    res = native_window_set_buffer_count(mConsumerInterface.get(),
            totalBuffers);
    if (res != OK) {
        ALOGE("%s: Unable to set buffer count for stream %d",
                __FUNCTION__, mId);
        mState = CONNECTED;
        return res;
    }

    // Register allocated buffers with HAL device
    buffer_handle_t *buffers = new buffer_handle_t[totalBuffers];
    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers];
    int bufferIdx = 0;
    for (; bufferIdx < totalBuffers; bufferIdx++) {
        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
                &anwBuffers[bufferIdx]);
        if (res != OK) {
            ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
                    "stream %d", __FUNCTION__, bufferIdx, mId);
            mState = CONNECTED;
            goto cleanUpBuffers;
        }
        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
    }

    res = mDevice->ops->register_stream_buffers(mDevice,
            mId,
            totalBuffers,
            buffers);
    if (res != OK) {
        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
                __FUNCTION__, mId);
        mState = CONNECTED;
    } else {
        mState = ACTIVE;
    }

cleanUpBuffers:
    for (int i = 0; i < bufferIdx; i++) {
        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
                anwBuffers[i], -1);
    }
    delete anwBuffers;
    delete buffers;

    return res;
}
Exemple #18
0
Error HWUISink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) const {
    // Do all setup in this function because we don't know the size
    // for the RenderNode and RenderProxy during the constructor.
    // In practice this doesn't seem too expensive.
    const SkISize size = src.size();

    // Based on android::SurfaceTexture_init()
    android::sp<android::IGraphicBufferProducer> producer;
    android::sp<android::IGraphicBufferConsumer> consumer;
    android::BufferQueue::createBufferQueue(&producer, &consumer);

    // Consumer setup

    android::sp<android::CpuConsumer> cpuConsumer =
        new android::CpuConsumer(consumer, 1);
    cpuConsumer->setName(android::String8("SkiaTestClient"));
    cpuConsumer->setDefaultBufferSize(size.width(), size.height());

    // Producer setup

    android::sp<android::Surface> surface = new android::Surface(producer);
    native_window_set_buffers_dimensions(surface.get(), size.width(), size.height());
    native_window_set_buffers_format(surface.get(), android::PIXEL_FORMAT_RGBA_8888);
    native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_READ_OFTEN |
                                           GRALLOC_USAGE_SW_WRITE_NEVER |
                                           GRALLOC_USAGE_HW_RENDER);

    // RenderNode setup based on hwui/tests/main.cpp:TreeContentAnimation
    SkAutoTDelete<android::uirenderer::RenderNode> rootNode
        (new android::uirenderer::RenderNode());
    rootNode->incStrong(nullptr);

    // Values set here won't be applied until the framework has called
    // RenderNode::pushStagingPropertiesChanges() during RenderProxy::syncAndDrawFrame().
    rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, size.width(), size.height());
    rootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::X |
                                     android::uirenderer::RenderNode::Y);
    rootNode->mutateStagingProperties().setClipToBounds(false);
    rootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::GENERIC);

    // RenderProxy setup based on hwui/tests/main.cpp:TreeContentAnimation
    ContextFactory factory;
    SkAutoTDelete<android::uirenderer::renderthread::RenderProxy> proxy
        (new android::uirenderer::renderthread::RenderProxy(false, rootNode, &factory));
    proxy->loadSystemProperties();

    proxy->initialize(surface.get());

    float lightX = size.width() / 2.0f;
    android::uirenderer::Vector3 lightVector { lightX, dp(-200.0f), dp(800.0f) };
    proxy->setup(size.width(), size.height(), lightVector, dp(800.0f), 255 * 0.075f, 255 * 0.15f,
                 kDensity);

    // Do the draw

    SkAutoTDelete<android::uirenderer::DisplayListRenderer> renderer
        (new android::uirenderer::DisplayListRenderer());
    renderer->setViewport(size.width(), size.height());
    renderer->prepare();
    renderer->clipRect(0, 0, size.width(), size.height(), SkRegion::Op::kReplace_Op);

    Error err = src.draw(renderer->asSkCanvas());
    if (!err.isEmpty()) {
        return err;
    }

    renderer->finish();
    rootNode->setStagingDisplayList(renderer->finishRecording());

    proxy->syncAndDrawFrame();
    proxy->fence();

    // Capture pixels

    SkImageInfo destinationConfig =
        SkImageInfo::Make(size.width(), size.height(),
                          kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    dst->allocPixels(destinationConfig);
    sk_memset32((uint32_t*) dst->getPixels(), SK_ColorRED, size.width() * size.height());

    android::CpuConsumer::LockedBuffer nativeBuffer;
    android::status_t retval = cpuConsumer->lockNextBuffer(&nativeBuffer);
    if (retval == android::BAD_VALUE) {
        SkDebugf("HWUISink::draw() got no buffer; returning transparent");
        // No buffer ready to read - commonly triggered by dm sending us
        // a no-op source, or calling code that doesn't do anything on this
        // backend.
        dst->eraseColor(SK_ColorTRANSPARENT);
        return "";
    } else if (retval) {
        return SkStringPrintf("Failed to lock buffer to read pixels: %d.", retval);
    }

    // Move the pixels into the destination SkBitmap

    SK_ALWAYSBREAK(nativeBuffer.format == android::PIXEL_FORMAT_RGBA_8888 &&
                   "Native buffer not RGBA!");
    SkImageInfo nativeConfig =
        SkImageInfo::Make(nativeBuffer.width, nativeBuffer.height,
                          kRGBA_8888_SkColorType, kPremul_SkAlphaType);

    // Android stride is in pixels, Skia stride is in bytes
    SkBitmap nativeWrapper;
    bool success =
        nativeWrapper.installPixels(nativeConfig, nativeBuffer.data, nativeBuffer.stride * 4);
    if (!success) {
        return "Failed to wrap HWUI buffer in a SkBitmap";
    }

    SK_ALWAYSBREAK(dst->colorType() == kRGBA_8888_SkColorType &&
                   "Destination buffer not RGBA!");
    success =
        nativeWrapper.readPixels(destinationConfig, dst->getPixels(), dst->rowBytes(), 0, 0);
    if (!success) {
        return "Failed to extract pixels from HWUI buffer";
    }

    cpuConsumer->unlockBuffer(nativeBuffer);
    return "";
}
Exemple #19
0
 void SurfaceUtils::setUsage(int usage) {
     native_window_set_usage(mWindow, usage);
 }
void
FakeSurfaceComposer::captureScreenImp(const sp<IGraphicBufferProducer>& producer,
                                      uint32_t reqWidth,
                                      uint32_t reqHeight,
                                      const sp<GraphicProducerWrapper>& wrapper)
{
    MOZ_ASSERT(NS_IsMainThread());
    MOZ_ASSERT(wrapper.get());

    RefPtr<nsScreenGonk> screen = nsScreenManagerGonk::GetPrimaryScreen();

    // get screen geometry
    nsIntRect screenBounds = screen->GetNaturalBounds().ToUnknownRect();
    const uint32_t hw_w = screenBounds.width;
    const uint32_t hw_h = screenBounds.height;

    if (reqWidth > hw_w || reqHeight > hw_h) {
        ALOGE("size mismatch (%d, %d) > (%d, %d)",
                reqWidth, reqHeight, hw_w, hw_h);
        static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(BAD_VALUE);
        return;
    }

    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
    reqHeight = (!reqHeight) ? hw_h : reqHeight;

    nsScreenGonk* screenPtr = screen.forget().take();
    nsCOMPtr<nsIRunnable> runnable =
        NS_NewRunnableFunction([screenPtr, reqWidth, reqHeight, producer, wrapper]() {
            // create a surface (because we're a producer, and we need to
            // dequeue/queue a buffer)
            sp<Surface> sur = new Surface(producer);
            ANativeWindow* window = sur.get();

            if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != NO_ERROR) {
                static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(BAD_VALUE);
                NS_ReleaseOnMainThread(screenPtr);
                return;
            }
            uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
                             GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;

            int err = 0;
            err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
            err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
            err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
            err |= native_window_set_usage(window, usage);

            status_t result = NO_ERROR;
            if (err == NO_ERROR) {
                ANativeWindowBuffer* buffer;
                result = native_window_dequeue_buffer_and_wait(window,  &buffer);
                if (result == NO_ERROR) {
                    nsresult rv = screenPtr->MakeSnapshot(buffer);
                    if (rv != NS_OK) {
                        result = INVALID_OPERATION;
                    }
                    window->queueBuffer(window, buffer, -1);
                }
            } else {
                result = BAD_VALUE;
            }
            native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
            static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
            NS_ReleaseOnMainThread(screenPtr);
        });

    mozilla::layers::CompositorParent::CompositorLoop()->PostTask(
        FROM_HERE, new RunnableCallTask(runnable));
}
void SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) {
    CHECK(format != NULL);

    int32_t colorFormatNew;
    CHECK(format->findInt32("color-format", &colorFormatNew));

    int32_t widthNew, heightNew;
    CHECK(format->findInt32("stride", &widthNew));
    CHECK(format->findInt32("slice-height", &heightNew));

    int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
    if (!format->findRect(
            "crop", &cropLeftNew, &cropTopNew, &cropRightNew, &cropBottomNew)) {
        cropLeftNew = cropTopNew = 0;
        cropRightNew = widthNew - 1;
        cropBottomNew = heightNew - 1;
    }

    if (static_cast<int32_t>(mColorFormat) == colorFormatNew &&
        mWidth == widthNew &&
        mHeight == heightNew &&
        mCropLeft == cropLeftNew &&
        mCropTop == cropTopNew &&
        mCropRight == cropRightNew &&
        mCropBottom == cropBottomNew) {
        // Nothing changed, no need to reset renderer.
        return;
    }

    mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew);
    mWidth = widthNew;
    mHeight = heightNew;
    mCropLeft = cropLeftNew;
    mCropTop = cropTopNew;
    mCropRight = cropRightNew;
    mCropBottom = cropBottomNew;

    mCropWidth = mCropRight - mCropLeft + 1;
    mCropHeight = mCropBottom - mCropTop + 1;

    int halFormat;
    size_t bufWidth, bufHeight;

    switch (mColorFormat) {
        case OMX_COLOR_FormatYUV420Planar:
        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
        case OMX_COLOR_FormatYUV420SemiPlanar:
        {
            if (!runningInEmulator()) {
                halFormat = HAL_PIXEL_FORMAT_YV12;
                bufWidth = (mCropWidth + 1) & ~1;
                bufHeight = (mCropHeight + 1) & ~1;
                break;
            }

            // fall through.
        }

        default:
            halFormat = HAL_PIXEL_FORMAT_RGB_565;
            bufWidth = mCropWidth;
            bufHeight = mCropHeight;

            mConverter = new ColorConverter(
                    mColorFormat, OMX_COLOR_Format16bitRGB565);
            CHECK(mConverter->isValid());
            break;
    }

    CHECK(mNativeWindow != NULL);
    CHECK(mCropWidth > 0);
    CHECK(mCropHeight > 0);
    CHECK(mConverter == NULL || mConverter->isValid());

    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));

    CHECK_EQ(0,
            native_window_set_scaling_mode(
            mNativeWindow.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    // Width must be multiple of 32???
    CHECK_EQ(0, native_window_set_buffers_dimensions(
                mNativeWindow.get(),
                bufWidth,
                bufHeight));
    CHECK_EQ(0, native_window_set_buffers_format(
                mNativeWindow.get(),
                halFormat));

    // NOTE: native window uses extended right-bottom coordinate
    android_native_rect_t crop;
    crop.left = mCropLeft;
    crop.top = mCropTop;
    crop.right = mCropRight + 1;
    crop.bottom = mCropBottom + 1;
    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);

    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));

    int32_t rotationDegrees;
    if (!format->findInt32("rotation-degrees", &rotationDegrees)) {
        rotationDegrees = 0;
    }
    uint32_t transform;
    switch (rotationDegrees) {
        case 0: transform = 0; break;
        case 90: transform = HAL_TRANSFORM_ROT_90; break;
        case 180: transform = HAL_TRANSFORM_ROT_180; break;
        case 270: transform = HAL_TRANSFORM_ROT_270; break;
        default: transform = 0; break;
    }

    CHECK_EQ(0, native_window_set_buffers_transform(
                mNativeWindow.get(), transform));
}
CedarXSoftwareRenderer::CedarXSoftwareRenderer(
        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
    : mYUVMode(None),
      mNativeWindow(nativeWindow) {
    int32_t tmp;
    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
    //mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;

    //CHECK(meta->findInt32(kKeyScreenID, &screenID));
    //CHECK(meta->findInt32(kKeyColorFormat, &halFormat));
    CHECK(meta->findInt32(kKeyWidth, &mWidth));
    CHECK(meta->findInt32(kKeyHeight, &mHeight));

    int32_t nVdecInitRotation;  //clock wise.
    int32_t rotationDegrees;    //anti-clock wise,
    if (!meta->findInt32(kKeyRotation, &nVdecInitRotation)) {
        LOGD("(f:%s, l:%d) find fail nVdecInitRotation[%d]", __FUNCTION__, __LINE__, nVdecInitRotation);
        rotationDegrees = 0;
    }
    else
    {
        switch(nVdecInitRotation)
        {
            case 0:
            {
                rotationDegrees = 0;
                break;
            }
            case 1:
            {
                rotationDegrees = 270;
                break;
            }
            case 2:
            {
                rotationDegrees = 180;
                break;
            }
            case 3:
            {
                rotationDegrees = 90;
                break;
            }
            default:
            {
                LOGW("(f:%s, l:%d) nInitRotation=%d", __FUNCTION__, __LINE__, nVdecInitRotation);
                rotationDegrees = 0;
                break;
            }
        }
    }
    meta->findInt32(kKey3dDoubleStream, &m3dModeDoubleStreamFlag);
    
    int GpuBufHeight_num = 0;
    int halFormat;
    size_t bufWidth, bufHeight;
    size_t nGpuBufWidth, nGpuBufHeight;
    if(0 == m3dModeDoubleStreamFlag)
    {
        GpuBufHeight_num = 1;
    }
    else
    {
        LOGD("(f:%s, l:%d) be careful for 3d double stream!", __FUNCTION__, __LINE__);
        GpuBufHeight_num = 2;
    }

    halFormat = HAL_PIXEL_FORMAT_YV12;
    bufWidth = mWidth;
    bufHeight = mHeight;
    if(bufWidth != ((mWidth + 15) & ~15))
    {
        LOGW("(f:%s, l:%d) bufWidth[%d]!=display_width[%d]", __FUNCTION__, __LINE__, ((mWidth + 15) & ~15), mWidth);
    }
    if(bufHeight != ((mHeight + 15) & ~15))
    {
        LOGW("(f:%s, l:%d) bufHeight[%d]!=display_height[%d]", __FUNCTION__, __LINE__, ((mHeight + 15) & ~15), mHeight);
    }

    CHECK(mNativeWindow != NULL);
    int usage = 0;
    meta->findInt32(kKeyIsDRM, &usage);
    if(usage) {
    	LOGV("protected video");
    	usage = GRALLOC_USAGE_PROTECTED;
    }
    usage |= GRALLOC_USAGE_SW_READ_NEVER /*| GRALLOC_USAGE_SW_WRITE_OFTEN*/
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;

    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            usage));

    CHECK_EQ(0,
            native_window_set_scaling_mode(
            mNativeWindow.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    // Width must be multiple of 32??? 
    nGpuBufWidth = mWidth;
    nGpuBufHeight = mHeight;
#if (defined(__CHIP_VERSION_F23) || (defined(__CHIP_VERSION_F51)))
  #if (1 == ADAPT_A10_GPU_RENDER)
    nGpuBufWidth = (mWidth + 15) & ~15;
    //A10's GPU has a bug, we can avoid it
    if(nGpuBufHeight%8 != 0)
    {
        LOGD("(f:%s, l:%d) original gpu buf align_width[%d], height[%d]mod8 = %d", __FUNCTION__, __LINE__, nGpuBufWidth, nGpuBufHeight, nGpuBufHeight%8);
        if((nGpuBufWidth*nGpuBufHeight)%256 != 0)
        {   // e:\videofile\test_stream\avi, 800*450
            LOGW("(f:%s, l:%d) original gpu buf align_width[%d]*height[%d]mod1024 = %d", __FUNCTION__, __LINE__, nGpuBufWidth, nGpuBufHeight, (nGpuBufWidth*nGpuBufHeight)%1024);
            nGpuBufHeight = (nGpuBufHeight+7)&~7;
            LOGW("(f:%s, l:%d) change gpu buf height to [%d]", __FUNCTION__, __LINE__, nGpuBufHeight);
        }
    }
    nGpuBufWidth = mWidth;  //restore GpuBufWidth to mWidth;
  #endif
#elif defined(__CHIP_VERSION_F33)
  #if (1 == ADAPT_A31_GPU_RENDER)
    //A31 GPU rect width should 8 align.
    if(mWidth%8 != 0)
    {
        nGpuBufWidth = (mWidth + 7) & ~7;
        LOGD("(f:%s, l:%d) A31 gpuBufWidth[%d]mod16=[%d] ,should 8 align, change to [%d]", __FUNCTION__, __LINE__, mWidth, mWidth%8, nGpuBufWidth);
    }
  #endif
#else
    #error "Unknown chip type!"
#endif
    CHECK_EQ(0, native_window_set_buffers_geometry(
                mNativeWindow.get(),
                //(bufWidth + 15) & ~15,
                //(bufHeight+ 15) & ~15,
                //(bufWidth + 15) & ~15,
                //bufHeight,
                //bufWidth,
                //bufHeight,
                nGpuBufWidth,
                nGpuBufHeight * GpuBufHeight_num,
                halFormat));
    uint32_t transform;
    switch (rotationDegrees) {
        case 0: transform = 0; break;
        case 90: transform = HAL_TRANSFORM_ROT_90; break;
        case 180: transform = HAL_TRANSFORM_ROT_180; break;
        case 270: transform = HAL_TRANSFORM_ROT_270; break;
        default: transform = 0; break;
    }

    if (transform) {
        LOGD("(f:%s, l:%d) transform[%d]", __FUNCTION__, __LINE__, transform);
        CHECK_EQ(0, native_window_set_buffers_transform(
                    mNativeWindow.get(), transform));
    }
    Rect crop;
    crop.left = 0;
    crop.top  = 0;
    crop.right = bufWidth;
    crop.bottom = bufHeight;
    mNativeWindow->perform(mNativeWindow.get(), NATIVE_WINDOW_SET_CROP, &crop);
}
status_t setNativeWindowSizeFormatAndUsage(
        ANativeWindow *nativeWindow /* nonnull */,
        int width, int height, int format, int rotation, int usage) {
    status_t err = native_window_set_buffers_dimensions(nativeWindow, width, height);
    if (err != NO_ERROR) {
        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err);
        return err;
    }

    err = native_window_set_buffers_format(nativeWindow, format);
    if (err != NO_ERROR) {
        ALOGE("native_window_set_buffers_format failed: %s (%d)", strerror(-err), -err);
        return err;
    }

    int transform = 0;
    if ((rotation % 90) == 0) {
        switch ((rotation / 90) & 3) {
            case 1:  transform = HAL_TRANSFORM_ROT_90;  break;
            case 2:  transform = HAL_TRANSFORM_ROT_180; break;
            case 3:  transform = HAL_TRANSFORM_ROT_270; break;
            default: transform = 0;                     break;
        }
    }

    err = native_window_set_buffers_transform(nativeWindow, transform);
    if (err != NO_ERROR) {
        ALOGE("native_window_set_buffers_transform failed: %s (%d)", strerror(-err), -err);
        return err;
    }

    // Make sure to check whether either Stagefright or the video decoder
    // requested protected buffers.
    if (usage & GRALLOC_USAGE_PROTECTED) {
        // Verify that the ANativeWindow sends images directly to
        // SurfaceFlinger.
        int queuesToNativeWindow = 0;
        err = nativeWindow->query(
                nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow);
        if (err != NO_ERROR) {
            ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err);
            return err;
        }
        if (queuesToNativeWindow != 1) {
            ALOGE("native window could not be authenticated");
            return PERMISSION_DENIED;
        }
    }

    int consumerUsage = 0;
    err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage);
    if (err != NO_ERROR) {
        ALOGW("failed to get consumer usage bits. ignoring");
        err = NO_ERROR;
    }

    int finalUsage = usage | consumerUsage;
    ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#x", usage, consumerUsage, finalUsage);
    err = native_window_set_usage(nativeWindow, finalUsage);
    if (err != NO_ERROR) {
        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
        return err;
    }

    err = native_window_set_scaling_mode(
            nativeWindow, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    if (err != NO_ERROR) {
        ALOGE("native_window_set_scaling_mode failed: %s (%d)", strerror(-err), -err);
        return err;
    }

    ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x",
            nativeWindow, width, height, format, rotation, finalUsage);
    return NO_ERROR;
}
SoftwareRenderer::SoftwareRenderer(
        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
    : mConverter(NULL),
      mYUVMode(None),
      mNativeWindow(nativeWindow) {
    int32_t tmp;
    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;

    CHECK(meta->findInt32(kKeyWidth, &mWidth));
    CHECK(meta->findInt32(kKeyHeight, &mHeight));

    if (!meta->findRect(
                kKeyCropRect,
                &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) {
        mCropLeft = mCropTop = 0;
        mCropRight = mWidth - 1;
        mCropBottom = mHeight - 1;
    }

    mCropWidth = mCropRight - mCropLeft + 1;
    mCropHeight = mCropBottom - mCropTop + 1;

    int32_t rotationDegrees;
    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
        rotationDegrees = 0;
    }

    int halFormat;
    size_t bufWidth, bufHeight;

    switch (mColorFormat) {
        case OMX_COLOR_FormatYUV420Planar:
        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
        {
            if (!runningInEmulator()) {
                halFormat = HAL_PIXEL_FORMAT_YV12;
                bufWidth = (mCropWidth + 1) & ~1;
                bufHeight = (mCropHeight + 1) & ~1;
                break;
            }

            // fall through.
        }
#ifdef QCOM_LEGACY_OMX
        case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
        {
            halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
            bufWidth = (mCropWidth + 1) & ~1;
            bufHeight = (mCropHeight + 1) & ~1;
            mAlign = ((mWidth + 15) & -16) * ((mHeight + 15) & -16);
            break;
        }
#endif

        default:
            halFormat = HAL_PIXEL_FORMAT_RGB_565;
            bufWidth = mCropWidth;
            bufHeight = mCropHeight;

            mConverter = new ColorConverter(
                    mColorFormat, OMX_COLOR_Format16bitRGB565);
            CHECK(mConverter->isValid());
            break;
    }

    ALOGI("Buffer color format: 0x%X", mColorFormat);
    ALOGI("Video params: mWidth: %d, mHeight: %d, mCropWidth: %d, mCropHeight: %d, mCropTop: %d, mCropLeft: %d",
         mWidth, mHeight, mCropWidth, mCropHeight, mCropTop, mCropLeft);

    CHECK(mNativeWindow != NULL);
    CHECK(mCropWidth > 0);
    CHECK(mCropHeight > 0);
    CHECK(mConverter == NULL || mConverter->isValid());

#ifdef EXYNOS4_ENHANCEMENTS
    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP
            | GRALLOC_USAGE_HW_FIMC1 | GRALLOC_USAGE_HWC_HWOVERLAY));
#else
    CHECK_EQ(0,
            native_window_set_usage(
            mNativeWindow.get(),
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP
#ifdef QCOM_LEGACY_OMX
            | GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED
#endif
            ));
#endif

    CHECK_EQ(0,
            native_window_set_scaling_mode(
            mNativeWindow.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));

    // Width must be multiple of 32???
    CHECK_EQ(0, native_window_set_buffers_geometry(
                mNativeWindow.get(),
                bufWidth,
                bufHeight,
                halFormat));

    uint32_t transform;
    switch (rotationDegrees) {
        case 0: transform = 0; break;
        case 90: transform = HAL_TRANSFORM_ROT_90; break;
        case 180: transform = HAL_TRANSFORM_ROT_180; break;
        case 270: transform = HAL_TRANSFORM_ROT_270; break;
        default: transform = 0; break;
    }

    if (transform) {
        CHECK_EQ(0, native_window_set_buffers_transform(
                    mNativeWindow.get(), transform));
    }
}
status_t Camera3OutputStream::configureQueueLocked() {
    status_t res;

    mTraceFirstBuffer = true;
    if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
        return res;
    }

    ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");

    // Configure consumer-side ANativeWindow interface
    res = native_window_api_connect(mConsumer.get(),
            NATIVE_WINDOW_API_CAMERA);
    if (res != OK) {
        ALOGE("%s: Unable to connect to native window for stream %d",
                __FUNCTION__, mId);
        return res;
    }

    res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
    if (res != OK) {
        ALOGE("%s: Unable to configure usage %08x for stream %d",
                __FUNCTION__, camera3_stream::usage, mId);
        return res;
    }

    res = native_window_set_scaling_mode(mConsumer.get(),
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    if (res != OK) {
        ALOGE("%s: Unable to configure stream scaling: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

    if (mMaxSize == 0) {
        // For buffers of known size
        res = native_window_set_buffers_dimensions(mConsumer.get(),
                camera3_stream::width, camera3_stream::height);
    } else {
        // For buffers with bounded size
        res = native_window_set_buffers_dimensions(mConsumer.get(),
                mMaxSize, 1);
    }
    if (res != OK) {
        ALOGE("%s: Unable to configure stream buffer dimensions"
                " %d x %d (maxSize %zu) for stream %d",
                __FUNCTION__, camera3_stream::width, camera3_stream::height,
                mMaxSize, mId);
        return res;
    }
    res = native_window_set_buffers_format(mConsumer.get(),
            camera3_stream::format);
    if (res != OK) {
        ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
                __FUNCTION__, camera3_stream::format, mId);
        return res;
    }

    int maxConsumerBuffers;
    res = mConsumer->query(mConsumer.get(),
            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
    if (res != OK) {
        ALOGE("%s: Unable to query consumer undequeued"
                " buffer count for stream %d", __FUNCTION__, mId);
        return res;
    }

    ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
            maxConsumerBuffers, camera3_stream::max_buffers);
    if (camera3_stream::max_buffers == 0) {
        ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
                __FUNCTION__, camera3_stream::max_buffers);
        return INVALID_OPERATION;
    }

    mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
    mHandoutTotalBufferCount = 0;
    mFrameCount = 0;
    mLastTimestamp = 0;

    res = native_window_set_buffer_count(mConsumer.get(),
            mTotalBufferCount);
    if (res != OK) {
        ALOGE("%s: Unable to set buffer count for stream %d",
                __FUNCTION__, mId);
        return res;
    }

    res = native_window_set_buffers_transform(mConsumer.get(),
            mTransform);
    if (res != OK) {
        ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
                __FUNCTION__, mTransform, strerror(-res), res);
    }

    return OK;
}
Exemple #26
0
bool_e anativewindow_allocate(anativewindow_t *anw,
                              uint32_t buffer_width,
                              uint32_t buffer_height,
                              int32_t numBuffers,
                              int32_t format,
                              bool flipH)
{
    if (format != ANW_NV12_FORMAT)
        return false_e;

    if (anw)
    {
        status_t status = 0;

        anw->m_format = format;
        anw->m_usage = GRALLOC_USAGE_HW_TEXTURE |
                       GRALLOC_USAGE_HW_RENDER |
                       GRALLOC_USAGE_SW_READ_OFTEN | // Non-cached ? If you use RARELY it will complain
                       GRALLOC_USAGE_SW_WRITE_NEVER; // can't access from UVA
        anw->m_numBuffers = numBuffers;
        anw->m_width = buffer_width;
        anw->m_height = buffer_height;
        anw->m_native_buffers = (ANativeWindowBuffer **)calloc(numBuffers, sizeof(ANativeWindowBuffer *));
        DVP_PRINT(DVP_ZONE_VIDEO, "Created %u pointers in native array %p\n", numBuffers, anw->m_native_buffers);
        if (anw->m_native_buffers == NULL) {
            return false_e;
        }

        // connect to the native window API
        status = native_window_api_connect(anw->m_window.get(), NATIVE_WINDOW_API_CAMERA);
        ANW_ERROR(status,"CONNECT");

        // set the scaling mode of the windows
        status = native_window_set_scaling_mode(anw->m_window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        ANW_ERROR(status,"SCALING");

#if defined(BLAZE_TABLET) && defined(ICS)
        // set the layout of the buffer
        status = native_window_set_buffers_layout(anw->m_window.get(), NATIVE_WINDOW_BUFFERS_LAYOUT_PROGRESSIVE); // progressive
        ANW_ERROR(status,"LAYOUT");
#endif

        // set the format of the buffer
        status = native_window_set_buffers_format(anw->m_window.get(), anw->m_format);
        ANW_ERROR(status,"FORMAT");

        // setup the dimensions
        status = native_window_set_buffers_dimensions(anw->m_window.get(), anw->m_width, anw->m_height);
        ANW_ERROR(status,"DIM");

        if (flipH) {
            // set the horizontal flip
            status = native_window_set_buffers_transform(anw->m_window.get(), NATIVE_WINDOW_TRANSFORM_FLIP_H);
            ANW_ERROR(status,"TRANSFORM FLIP HORIZONTAL");
        }

        // set the usage of the GRALLOC buffers
        status = native_window_set_usage(anw->m_window.get(), anw->m_usage);
        if (status < 0 ) {
            DVP_PRINT(DVP_ZONE_ERROR, "%s[%u] USAGE status = %d (0x%08x)\n", __FUNCTION__, __LINE__, status, anw->m_usage);
        }

        // set the number of buffers required.
        status = native_window_set_buffer_count(anw->m_window.get(), anw->m_numBuffers);
        ANW_ERROR(status,"COUNT");

        // get the number of dequeueable buffers
        status = anw->m_window->query(anw->m_window.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, (int*)&anw->m_nonqueue);
        ANW_ERROR(status,"QUERY NONQUEUE");

        for (uint32_t n = 0; n < anw->m_numBuffers; n++)
        {
            status = anw->m_window->dequeueBuffer(anw->m_window.get(), &anw->m_native_buffers[n]);
            if (status != 0) {
                DVP_PRINT(DVP_ZONE_ERROR, "%s[%u] %s status = %d\n", __FUNCTION__, __LINE__, "Failed window buffer dequeue!", status); \
                return false_e;
            }
            if (anw->m_native_buffers[n])
            {
                native_handle_t *hdl = (native_handle_t *)anw->m_native_buffers[n]->handle;
                hdl = hdl; // warnings
                DVP_PRINT(DVP_ZONE_VIDEO, "ANativeBuffer %p => dim %dx%d stride %d usage %d format %d handle %p numFds=%u\n",
                         anw->m_native_buffers[n],
                         anw->m_native_buffers[n]->width,
                         anw->m_native_buffers[n]->height,
                         anw->m_native_buffers[n]->stride,
                         anw->m_native_buffers[n]->usage,
                         anw->m_native_buffers[n]->format,
                         anw->m_native_buffers[n]->handle,
                         hdl->numFds);
            }
        }
        return true_e;
    }
    return false_e;
}