EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
                                    NativeWindowType window,
                                    const EGLint *attrib_list)
{
    clearError();

    egl_connection_t* cnx = NULL;
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;
        EGLint format;

        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
            ALOGE("EGLNativeWindowType %p already connected to another API",
                    window);
            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
        }

        // set the native window's buffers format to match this config
        if (cnx->egl.eglGetConfigAttrib(iDpy,
                config, EGL_NATIVE_VISUAL_ID, &format)) {
            if (format != 0) {
                int err = native_window_set_buffers_format(window, format);
                if (err != 0) {
                    ALOGE("error setting native window pixel format: %s (%d)",
                            strerror(-err), err);
                    native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                    return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
                }
            }
        }

        // the EGL spec requires that a new EGLSurface default to swap interval
        // 1, so explicitly set that on the window here.
        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
        anw->setSwapInterval(anw, 1);

        EGLSurface surface = cnx->egl.eglCreateWindowSurface(
                iDpy, config, window, attrib_list);
        if (surface != EGL_NO_SURFACE) {
            egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
                    surface, cnx);
            return s;
        }

        // EGLSurface creation failed
        native_window_set_buffers_format(window, 0);
        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
    }
    return EGL_NO_SURFACE;
}
int StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
        int64_t timestamp,
        buffer_handle_t* buffer) {
    int state = static_cast<const StreamAdapter*>(w)->mState;
    if (state != ACTIVE) {
        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
        return INVALID_OPERATION;
    }
    ANativeWindow *a = toANW(w);
    status_t err;
    err = native_window_set_buffers_timestamp(a, timestamp);
    if (err != OK) return err;
    return a->queueBuffer(a,
            container_of(buffer, ANativeWindowBuffer, handle), -1);
}
Example #3
0
nsWindow::nsWindow()
{
    mFramebuffer = nullptr;

    if (sScreenInitialized)
        return;

    sScreenOnEvent = new ScreenOnOffEvent(true);
    ClearOnShutdown(&sScreenOnEvent);
    sScreenOffEvent = new ScreenOnOffEvent(false);
    ClearOnShutdown(&sScreenOffEvent);
    GetGonkDisplay()->OnEnabled(displayEnabledCallback);

    nsIntSize screenSize;

    ANativeWindow *win = GetGonkDisplay()->GetNativeWindow();

    if (win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width) ||
        win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height)) {
        NS_RUNTIMEABORT("Failed to get native window size, aborting...");
    }
    gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);

    char propValue[PROPERTY_VALUE_MAX];
    property_get("ro.sf.hwrotation", propValue, "0");
    sPhysicalScreenRotation = atoi(propValue) / 90;

    sVirtualBounds = gScreenBounds;

    sScreenInitialized = true;

    nsAppShell::NotifyScreenInitialized();

    // This is a hack to force initialization of the compositor
    // resources, if we're going to use omtc.
    //
    // NB: GetPlatform() will create the gfxPlatform, which wants
    // to know the color depth, which asks our native window.
    // This has to happen after other init has finished.
    gfxPlatform::GetPlatform();
    if (!ShouldUseOffMainThreadCompositing()) {
        MOZ_CRASH("How can we render apps, then?");
    }
    // Update sUsingHwc whenever layers.composer2d.enabled changes
    Preferences::AddBoolVarCache(&sUsingHwc, "layers.composer2d.enabled");
}
Example #4
0
EGLBoolean egl_window_surface_t::swapBuffers()
{
    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);

    rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);

    nativeWindow->queueBuffer_DEPRECATED(nativeWindow, buffer);
    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer)) {
        buffer = NULL;
        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
    }

    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
            ((cb_handle_t *)(buffer->handle))->hostHandle);

    return EGL_TRUE;
}
int
HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur, gl::GLContext* aGLContext)
{
    MOZ_ASSERT(!Initialized());

    mHwc = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
    if (!mHwc) {
        LOGE("Failed to initialize hwc");
        return -1;
    }

    nsIntSize screenSize;

    ANativeWindow *win = GetGonkDisplay()->GetNativeWindow();
    win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width);
    win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height);
    mScreenRect = nsIntRect(nsIntPoint(0, 0), screenSize);

#if ANDROID_VERSION >= 17
    int supported = 0;

    if (mHwc->query) {
        if (mHwc->query(mHwc, HwcUtils::HWC_COLOR_FILL, &supported) == NO_ERROR) {
            mColorFill = !!supported;
        }
        if (mHwc->query(mHwc, HwcUtils::HWC_FORMAT_RB_SWAP, &supported) == NO_ERROR) {
            mRBSwapSupport = !!supported;
        }
    } else {
        mColorFill = false;
        mRBSwapSupport = false;
    }
#else
    char propValue[PROPERTY_VALUE_MAX];
    property_get("ro.display.colorfill", propValue, "0");
    mColorFill = (atoi(propValue) == 1) ? true : false;
    mRBSwapSupport = true;
#endif

    mDpy = dpy;
    mSur = sur;
    mGLContext = aGLContext;

    return 0;
}
Example #6
0
int IOMXHWBuffer_GetMinUndequeued( void *window, unsigned int *min_undequeued )
{
    ANativeWindow *anw = (ANativeWindow *)window;
    status_t err;

    CHECK_ANW();
#if ANDROID_API >= 11
    err = anw->query( anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued );
    CHECK_ERR();
#endif
    /* set a minimum value of min_undequeued in case query fails */
    if( *min_undequeued == 0 )
        *min_undequeued = 2;

    LOGD( "IOMXHWBuffer_GetMinUndequeued: %p %u", anw, *min_undequeued );

    return 0;
}
Example #7
0
int IOMXHWBuffer_Cancel( void *window, void *p_handle )
{
    ANativeWindow *anw = (ANativeWindow *)window;
    ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
    status_t err = NO_ERROR;

    CHECK_ANW();
    CHECK_ANB();

#if ANDROID_API >= 18
    err = anw->cancelBuffer_DEPRECATED( anw, anb );
#else
    err = anw->cancelBuffer( anw, anb );
#endif
    CHECK_ERR();

    return 0;
}
Example #8
0
int IOMXHWBuffer_Dequeue( void *window, void **pp_handle )
{
    ANativeWindow *anw = (ANativeWindow *)window;
    ANativeWindowBuffer_t *anb;
    status_t err = NO_ERROR;

    CHECK_ANW();

#if ANDROID_API >= 18
    err = anw->dequeueBuffer_DEPRECATED( anw, &anb );
#else
    err = anw->dequeueBuffer( anw, &anb );
#endif
    CHECK_ERR();

    *pp_handle = anb;

    return 0;
}
Example #9
0
EGLBoolean egl_window_surface_t::init()
{
    if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
    }
    nativeWindow->lockBuffer(nativeWindow, buffer);

    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
    rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
            getWidth(), getHeight());
    if (!rcSurface) {
        ALOGE("rcCreateWindowSurface returned 0");
        return EGL_FALSE;
    }
    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
            ((cb_handle_t*)(buffer->handle))->hostHandle);

    return EGL_TRUE;
}
Example #10
0
void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
{
  Vector<BufferItem> releasingVideoBuffers;
  {
    Mutex::Autolock autoLock(mPendingVideoBuffersLock);

    int size = mPendingVideoBuffers.size();
    for (int i = 0; i < size; i++) {
      releasingVideoBuffers.push(mPendingVideoBuffers[i]);
    }
    mPendingVideoBuffers.clear();
  }
  // Free all pending video buffers without holding mPendingVideoBuffersLock.
  int size = releasingVideoBuffers.size();
  for (int i = 0; i < size; i++) {
    MediaBuffer *buffer;
    buffer = releasingVideoBuffers[i].mMediaBuffer;
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
    android::sp<Fence> fence;
    int fenceFd = -1;
    fence = releasingVideoBuffers[i].mReleaseFenceHandle.mFence;
    if (fence.get() && fence->isValid()) {
      fenceFd = fence->dup();
    }
    MOZ_ASSERT(buffer->refcount() == 1);
    // This code expect MediaBuffer's ref count is 1.
    // Return gralloc buffer to ANativeWindow
    ANativeWindow* window = static_cast<ANativeWindow*>(mNativeWindowClient.get());
    window->cancelBuffer(window,
                         buffer->graphicBuffer().get(),
                         fenceFd);
    // Mark MediaBuffer as rendered.
    // When gralloc buffer is directly returned to ANativeWindow,
    // this mark is necesary.
    sp<MetaData> metaData = buffer->meta_data();
    metaData->setInt32(kKeyRendered, 1);
#endif
    // Return MediaBuffer to OMXCodec.
    buffer->release();
  }
  releasingVideoBuffers.clear();
}
int main(int argc, char** argv)
{
    // set up the thread-pool
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // create a client to surfaceflinger
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    
    sp<SurfaceControl> surfaceControl = client->createSurface(
            String8("surface"), 160, 240, PIXEL_FORMAT_RGB_565, 0);
    SurfaceComposerClient::openGlobalTransaction();
    surfaceControl->setLayer(100000);
    SurfaceComposerClient::closeGlobalTransaction();

    // pretend it went cross-process
    Parcel parcel;
    SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel);
    parcel.setDataPosition(0);
    sp<Surface> surface = Surface::readFromParcel(parcel);
    ANativeWindow* window = surface.get();

    printf("window=%p\n", window);

    int err = native_window_set_buffer_count(window, 8);
    ANativeWindowBuffer* buffer;

    for (int i=0 ; i<8 ; i++) {
        window->dequeueBuffer(window, &buffer);
        printf("buffer %d: %p\n", i, buffer);
    }

    printf("test complete. CTRL+C to finish.\n");

    IPCThreadState::self()->joinThreadPool();
    return 0;
}
extern "C" void
Java_org_mozilla_testuniversalsurfacetexture_TestUniversalSurfaceTexture_attachTexture(JNIEnv*
    aJEnv, jclass klass, jobject aSurface, int aDestroyed)
{
    __android_log_print(ANDROID_LOG_ERROR, "TUST", "### point a");

    if (!sSurfaceClass) {
        sSurfaceClass = reinterpret_cast<jclass>
            (aJEnv->NewGlobalRef(aJEnv->FindClass("android/view/Surface")));
        sNativeSurfaceField = aJEnv->GetFieldID(sSurfaceClass, "mNativeSurface", "I");
        sSurfaceControlField = aJEnv->GetFieldID(sSurfaceClass, "mSurfaceControl", "I");

        void* lib = dlopen("libui.so", RTLD_LAZY);
        sw_gralloc_handle_t_lock = (typeof(sw_gralloc_handle_t_lock))
            dlsym(lib, "_ZN7android19sw_gralloc_handle_t4lockEPS0_iiiiiPPv");
        sw_gralloc_handle_t_unlock = (typeof(sw_gralloc_handle_t_unlock))
            dlsym(lib, "_ZN7android19sw_gralloc_handle_t6unlockEPS0_");
        __android_log_print(ANDROID_LOG_ERROR, "TUST", "### Lock=%p, unlock=%p",
                            sw_gralloc_handle_t_lock, sw_gralloc_handle_t_unlock);

        lib = dlopen("libhardware.so", RTLD_LAZY);
        hw_get_module = (typeof(hw_get_module))dlsym(lib, "hw_get_module");

        hw_module_t* pModule;
        hw_get_module("gralloc", &pModule);
        sModule = reinterpret_cast<gralloc_module_t*>(pModule);
        __android_log_print(ANDROID_LOG_ERROR, "TUST", "### Gralloc module=%p", pModule);
    }

    if (!sImage) {
        ANativeWindow* nativeWindow = reinterpret_cast<ANativeWindow*>
            (aJEnv->GetIntField(aSurface, sNativeSurfaceField) + 8);

        /*Rect rect;
        rect.left = rect.top = rect.right = rect.bottom = 0;
        nativeWindow->perform(nativeWindow, NATIVE_WINDOW_SET_CROP, &rect);*/

        // NB: nativeWindow->common.magic is '_wnd' as a FourCC.
        // My version is 104.

        __android_log_print(ANDROID_LOG_ERROR, "TUST",
                            "### Native window ptr %p, magic %08x, version %d, reserved %p, flags %d, dpi %g\n",
                            nativeWindow, (unsigned)nativeWindow->common.magic,
                            nativeWindow->common.version, nativeWindow->common.reserved[0],
                            (int)nativeWindow->flags, (double)nativeWindow->xdpi);

        nativeWindow->dequeueBuffer(nativeWindow, &sBuffer);
        nativeWindow->lockBuffer(nativeWindow, sBuffer);

        // Must increment the refcount on the native window to avoid crashes on Mali (Galaxy S2).
        nativeWindow->common.incRef(&nativeWindow->common);

        const EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };

        sBuffer->common.incRef(&sBuffer->common);

        sImage = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
                                     EGL_NATIVE_BUFFER_ANDROID,
                                     reinterpret_cast<EGLClientBuffer>(sBuffer), eglImgAttrs);

        //nativeWindow->queueBuffer(nativeWindow, sBuffer);
    }

    uint8_t *bits = 0;
    int err = sModule->lock(sModule, sBuffer->handle, GRALLOC_USAGE_SW_READ_OFTEN |
                            GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, 512, 512, (void**)&bits);
    __android_log_print(ANDROID_LOG_ERROR, "TUST",
                "### Buffer width=%d height=%d stride=%d format=%d usage=%d Bits are: %p, err=%d",
                sBuffer->width, sBuffer->height, sBuffer->stride, sBuffer->format, sBuffer->usage,
                bits, err);

    struct timeval tv;
    gettimeofday(&tv, NULL);

    static int x = 0;

    for (int i = 0; i < 512*512*2; i += 2) {
        bits[i] = bits[i+1] = (tv.tv_usec / 100000) % 256;
    }
    sModule->unlock(sModule, sBuffer->handle);

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, sImage);

    __android_log_print(ANDROID_LOG_ERROR, "TUST", "### Success! GL error is: %d",
                        (int)glGetError());
}
Example #13
0
void egl_window_surface_t::setSwapInterval(int interval)
{
    nativeWindow->setSwapInterval(nativeWindow, interval);
}
Example #14
0
EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
                                    NativeWindowType window,
                                    const EGLint *attrib_list)
{
    clearError();

    egl_connection_t* cnx = NULL;
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;

        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
            ALOGE("EGLNativeWindowType %p already connected to another API",
                    window);
            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
        }

        // Set the native window's buffers format to match what this config requests.
        // Whether to use sRGB gamma is not part of the EGLconfig, but is part
        // of our native format. So if sRGB gamma is requested, we have to
        // modify the EGLconfig's format before setting the native window's
        // format.
#if WORKAROUND_BUG_10194508
#warning "WORKAROUND_10194508 enabled"
        EGLint format;
        if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
                &format)) {
            ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
                    eglGetError());
            format = 0;
        }
        if (attrib_list) {
            for (const EGLint* attr = attrib_list; *attr != EGL_NONE;
                    attr += 2) {
                if (*attr == EGL_GL_COLORSPACE_KHR &&
                        dp->haveExtension("EGL_KHR_gl_colorspace")) {
                    if (ENABLE_EGL_KHR_GL_COLORSPACE) {
                        format = modifyFormatColorspace(format, *(attr+1));
                    } else {
                        // Normally we'd pass through unhandled attributes to
                        // the driver. But in case the driver implements this
                        // extension but we're disabling it, we want to prevent
                        // it getting through -- support will be broken without
                        // our help.
                        ALOGE("sRGB window surfaces not supported");
                        return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
                    }
                }
            }
        }
#else
        // by default, just pick RGBA_8888
        EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;

        EGLint a = 0;
        cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
        if (a > 0) {
            // alpha-channel requested, there's really only one suitable format
            format = HAL_PIXEL_FORMAT_RGBA_8888;
        } else {
            EGLint r, g, b;
            r = g = b = 0;
            cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE,   &r);
            cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g);
            cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE,  &b);
            EGLint colorDepth = r + g + b;
            if (colorDepth <= 16) {
                format = HAL_PIXEL_FORMAT_RGB_565;
            } else {
                format = HAL_PIXEL_FORMAT_RGBX_8888;
            }
        }

        // now select a corresponding sRGB format if needed
        if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
            for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
                if (*attr == EGL_GL_COLORSPACE_KHR) {
                    if (ENABLE_EGL_KHR_GL_COLORSPACE) {
                        format = modifyFormatColorspace(format, *(attr+1));
                    } else {
                        // Normally we'd pass through unhandled attributes to
                        // the driver. But in case the driver implements this
                        // extension but we're disabling it, we want to prevent
                        // it getting through -- support will be broken without
                        // our help.
                        ALOGE("sRGB window surfaces not supported");
                        return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
                    }
                }
            }
        }
#endif
        if (format != 0) {
            int err = native_window_set_buffers_format(window, format);
            if (err != 0) {
                ALOGE("error setting native window pixel format: %s (%d)",
                        strerror(-err), err);
                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
            }
        }

        // the EGL spec requires that a new EGLSurface default to swap interval
        // 1, so explicitly set that on the window here.
        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
        anw->setSwapInterval(anw, 1);

        EGLSurface surface = cnx->egl.eglCreateWindowSurface(
                iDpy, config, window, attrib_list);
        if (surface != EGL_NO_SURFACE) {
            egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
                    surface, cnx);
            return s;
        }

        // EGLSurface creation failed
        native_window_set_buffers_format(window, 0);
        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
    }
    return EGL_NO_SURFACE;
}
bool
GonkDisplayICS::QueueBuffer(ANativeWindowBuffer *buf)
{
    ANativeWindow *window = static_cast<ANativeWindow *>(mFBSurface.get());
    return !window->queueBuffer(window, buf);
}
status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration)
{
    ATRACE_CALL();

    status_t res;
    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;

    Mutex::Autolock icl(mBinderSerializationLock);


    sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
    if (bufferProducer == NULL) {
        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
        return BAD_VALUE;
    }
    if (!mDevice.get()) return DEAD_OBJECT;

    // Don't create multiple streams for the same target surface
    {
        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
        if (index != NAME_NOT_FOUND) {
            ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
                  "(ID %zd)",
                  __FUNCTION__, mCameraId, index);
            return ALREADY_EXISTS;
        }
    }

    // HACK b/10949105
    // Query consumer usage bits to set async operation mode for
    // GLConsumer using controlledByApp parameter.
    bool useAsync = false;
    int32_t consumerUsage;
    if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
            &consumerUsage)) != OK) {
        ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
              mCameraId);
        return res;
    }
    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
                __FUNCTION__, mCameraId);
        useAsync = true;
    }

    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
                              GRALLOC_USAGE_RENDERSCRIPT;
    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
                           GraphicBuffer::USAGE_HW_TEXTURE |
                           GraphicBuffer::USAGE_HW_COMPOSER;
    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
            (consumerUsage & allowedFlags) != 0;

    sp<IBinder> binder = IInterface::asBinder(bufferProducer);
    sp<Surface> surface = new Surface(bufferProducer, useAsync);
    ANativeWindow *anw = surface.get();

    int width, height, format;
    android_dataspace dataSpace;

    if ((res = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
        ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
              mCameraId);
        return res;
    }
    if ((res = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
        ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
              mCameraId);
        return res;
    }
    if ((res = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
        ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
              mCameraId);
        return res;
    }
    if ((res = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
                            reinterpret_cast<int*>(&dataSpace))) != OK) {
        ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__,
              mCameraId);
        return res;
    }

    // FIXME: remove this override since the default format should be
    //       IMPLEMENTATION_DEFINED. b/9487482
    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
        ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
              __FUNCTION__, mCameraId, format);
        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    }

    // Round dimensions to the nearest dimensions available for this format
    if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
            format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
        ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.",
                __FUNCTION__, format);
        return BAD_VALUE;
    }

    int streamId = -1;
    res = mDevice->createStream(surface, width, height, format, dataSpace,
                                static_cast<camera3_stream_rotation_t>
                                        (outputConfiguration.getRotation()),
                                &streamId);

    if (res == OK) {
        mStreamMap.add(binder, streamId);

        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
              __FUNCTION__, mCameraId, streamId);

        /**
         * Set the stream transform flags to automatically
         * rotate the camera stream for preview use cases.
         */
        int32_t transform = 0;
        res = getRotationTransformLocked(&transform);

        if (res != OK) {
            // Error logged by getRotationTransformLocked.
            return res;
        }

        res = mDevice->setStreamTransform(streamId, transform);
        if (res != OK) {
            ALOGE("%s: Failed to set stream transform (stream id %d)",
                  __FUNCTION__, streamId);
            return res;
        }

        return streamId;
    }

    return res;
}
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));
}
Example #18
0
status_t s3d_camera_test(void)
{
 	printf("[Unit Test] SurfaceFlinger 3D display test !\n\n");

    sp<SurfaceComposerClient> client;    
    //sp<SurfaceControl>        u;
    //sp<SurfaceControl>        c;
    sp<Surface>               s;
    Surface::SurfaceInfo      i;
    SkBitmap                  sbs;
    SkBitmap                  cam;

    // ready the png image file
    if (false == SkImageDecoder::DecodeFile("/data/3D_Camera_SBS.png", &sbs) ||
        false == SkImageDecoder::DecodeFile("/data/camera.png", &cam)) {
        printf("fail load file");
        return INVALID_OPERATION;
    }

    // create layer env
    client = new SurfaceComposerClient();
    printf("screen (w, h) = (%d, %d)\n\n",
        (int)client->getDisplayWidth(0), (int)client->getDisplayHeight(0));

    // test set to side by side mode, and pull to topest layer in transaction
    printf("*** camera test ...\n");

    u = client->createSurface(String8("test-ui"), 0, DRAW_FHD_W, DRAW_FHD_H, PIXEL_FORMAT_BGRA_8888);
    c = client->createSurface(String8("test-camera"), 0, DRAW_FHD_W, DRAW_FHD_H, PIXEL_FORMAT_RGBX_8888);
    
    client->openGlobalTransaction();
    {
        u->setLayer(210000);
        c->setLayer(200000);
    }
	client->closeGlobalTransaction();

    ANativeWindow       *w;                                        // fill camera surface
    ANativeWindowBuffer *buf;
    void                *ptr;
    const Rect          rect0(544, 960);
    const Rect          rect1(960, 540);

    s = u->getSurface();    // fill ui surface
    s->lock(&i);
    {        
        printf("lock ui, i.s=%d, i.h=%d\n",i.s, i.h);
        memset(i.bits, 0, i.s * i.h * 4);
        memcpy(i.bits, cam.getPixels(), 544 * 960 * 4);//buffer stride is bigger then ...
    }
    s->unlockAndPost();


    s = c->getSurface();
    w = s.get();
    native_window_api_connect(w, NATIVE_WINDOW_API_CAMERA);
    native_window_set_buffers_dimensions(w, 960, 540);
    native_window_set_buffers_format(w, HAL_PIXEL_FORMAT_RGBX_8888);
    native_window_set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_S3D_TOP_AND_BOTTOM);
    native_window_set_scaling_mode(w, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    native_window_set_buffers_transform(w, HAL_TRANSFORM_ROT_90);

    w->dequeueBuffer(w, &buf);
    GraphicBufferMapper::getInstance().lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, rect1, &ptr);
    {
        memcpy(ptr, sbs.getPixels(), 960 * 540 * 4);
    }
    GraphicBufferMapper::getInstance().unlock(buf->handle);    // inlock to return buffer
    w->queueBuffer(w, buf);                                    // queue to display


    uint8_t j = 0x80;

    client->openGlobalTransaction();
    {
        u->setAlpha(j);
    }
    client->closeGlobalTransaction();

    sleep(1);

    client->dispose();
    return NO_ERROR;   
}