status_t Camera3OutputStream::disconnectLocked() { status_t res; if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) { return res; } res = native_window_api_disconnect(mConsumer.get(), NATIVE_WINDOW_API_CAMERA); /** * This is not an error. if client calling process dies, the window will * also die and all calls to it will return DEAD_OBJECT, thus it's already * "disconnected" */ if (res == DEAD_OBJECT) { ALOGW("%s: While disconnecting stream %d from native window, the" " native window died from under us", __FUNCTION__, mId); } else if (res != OK) { ALOGE("%s: Unable to disconnect stream %d from native window " "(error %d %s)", __FUNCTION__, mId, res, strerror(-res)); mState = STATE_ERROR; return res; } mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG : STATE_CONSTRUCTED; return OK; }
EglWindowSurfaceImpl::~EglWindowSurfaceImpl() { if (android_buffer_) { android_window_->cancelBuffer_DEPRECATED(android_window_, android_buffer_); android_buffer_ = NULL; } native_window_api_disconnect(android_window_, NATIVE_WINDOW_API_EGL); android_window_->common.decRef(&android_window_->common); android_window_ = NULL; }
EGLSurface EglWindowSurfaceImpl::Create(EGLDisplay dpy, EGLConfig cfg, ANativeWindow* window, EGLint* out_error) { LOG_ALWAYS_FATAL_IF(out_error == NULL); *out_error = EGL_SUCCESS; EGLint format = 0; EGLint sfc_type = 0; EglDisplayImpl* display = EglDisplayImpl::GetDisplay(dpy); if (!display->GetConfigAttribute(cfg, EGL_NATIVE_VISUAL_ID, &format)) { ALOGE("Unable to get native visual format."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } else if (!display->GetConfigAttribute(cfg, EGL_SURFACE_TYPE, &sfc_type)) { ALOGE("Unable to get surface type."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } else if (!(sfc_type & EGL_WINDOW_BIT)) { ALOGE("Must support EGL_WINDOW_BIT surface types."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } else if (!window) { ALOGE("No native window provided."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } else if (window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { ALOGE("Invalid native window."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } else if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != android::OK) { ALOGE("Could not connect to native window."); *out_error = EGL_BAD_ALLOC; return EGL_NO_SURFACE; } int width = 0; window->query(window, NATIVE_WINDOW_WIDTH, &width); int height = 0; window->query(window, NATIVE_WINDOW_HEIGHT, &height); if (format != 0) { native_window_set_buffers_format(window, format); } window->setSwapInterval(window, 1); SurfacePtr s(new EglWindowSurfaceImpl(dpy, cfg, sfc_type, width, height, window)); if (s == NULL) { native_window_set_buffers_format(window, 0); native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); *out_error = EGL_BAD_ALLOC; return EGL_NO_DISPLAY; } return display->GetSurfaces().Register(s); }
static void disconnectWindow(const sp<ANativeWindow>& window) { if (window != 0) { status_t result = native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_CAMERA); if (result != NO_ERROR) { LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result), result); } } }
egl_surface_t::~egl_surface_t() { ANativeWindow* const window = win.get(); if (window != NULL) { native_window_set_buffers_format(window, 0); if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) { ALOGW("EGLNativeWindowType %p disconnect failed", window); } getDisplay()->onWindowSurfaceDestroyed(); } }
int IOMXHWBuffer_Disconnect( void *window ) { ANativeWindow *anw = (ANativeWindow *)window; CHECK_ANW(); #if ANDROID_API >= 14 native_window_api_disconnect( anw, NATIVE_WINDOW_API_MEDIA ); #endif return 0; }
status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { if (mDevice == NULL) { return OK; } mParameters.set(CameraParameters::KEY_FLASH_MODE, CameraParameters::FLASH_MODE_OFF); mDevice->setParameters(mParameters); mDevice->stopPreview(); status_t res = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_CAMERA); if (res) { ALOGW("%s: native_window_api_disconnect failed: %s (%d)", __FUNCTION__, strerror(-res), res); } mDevice->setPreviewWindow(NULL); mDevice->release(); return OK; }
void anativewindow_free(anativewindow_t *anw) { status_t status; GraphicBufferMapper &mapper = GraphicBufferMapper::get(); for (uint32_t i = 0; i < anw->m_numBuffers; i++) { if (anw->m_native_buffers[i]) { status = mapper.unlock((buffer_handle_t)anw->m_native_buffers[i]->handle); ANW_ERROR(status,"UNLOCK"); status = anw->m_window->cancelBuffer(anw->m_window.get(), anw->m_native_buffers[i]); ANW_ERROR(status,"CANCEL"); } } // disconnect from the native window status = native_window_api_disconnect(anw->m_window.get(), NATIVE_WINDOW_API_CAMERA); ANW_ERROR(status,"DISCONNECT"); anw->m_window.clear(); free(anw->m_native_buffers); }
status_t StreamAdapter::disconnect() { status_t res; if (mState >= ALLOCATED) { res = mDevice->ops->release_stream(mDevice, mId); if (res != OK) { ALOGE("%s: Unable to release stream %d", __FUNCTION__, mId); return res; } } if (mState >= CONNECTED) { res = native_window_api_disconnect(mConsumerInterface.get(), NATIVE_WINDOW_API_CAMERA); if (res != OK) { ALOGE("%s: Unable to disconnect stream %d from native window", __FUNCTION__, mId); return res; } } mId = -1; mState = DISCONNECTED; return OK; }
void SurfaceUtils::disconnectAPI(int api) { native_window_api_disconnect(mWindow, api); }
status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */) { status_t err = NO_ERROR; ANativeWindowBuffer* anb = NULL; int numBufs = 0; int minUndequeuedBufs = 0; // We need to reconnect to the ANativeWindow as a CPU client to ensure that // no frames get dropped by SurfaceFlinger assuming that these are video // frames. err = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err != NO_ERROR) { ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", strerror(-err), -err); return err; } err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_CPU); if (err != NO_ERROR) { ALOGE("error pushing blank frames: api_connect failed: %s (%d)", strerror(-err), -err); (void)native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA); return err; } err = setNativeWindowSizeFormatAndUsage( nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN); if (err != NO_ERROR) { goto error; } static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->allowAllocation(true); err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); if (err != NO_ERROR) { ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " "failed: %s (%d)", strerror(-err), -err); goto error; } numBufs = minUndequeuedBufs + 1; err = native_window_set_buffer_count(nativeWindow, numBufs); if (err != NO_ERROR) { ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", strerror(-err), -err); goto error; } // We push numBufs + 1 buffers to ensure that we've drawn into the same // buffer twice. This should guarantee that the buffer has been displayed // on the screen and then been replaced, so an previous video frames are // guaranteed NOT to be currently displayed. for (int i = 0; i < numBufs + 1; i++) { err = native_window_dequeue_buffer_and_wait(nativeWindow, &anb); if (err != NO_ERROR) { ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", strerror(-err), -err); break; } sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); // Fill the buffer with the a 1x1 checkerboard pattern ;) uint32_t *img = NULL; err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); if (err != NO_ERROR) { ALOGE("error pushing blank frames: lock failed: %s (%d)", strerror(-err), -err); break; } *img = 0; err = buf->unlock(); if (err != NO_ERROR) { ALOGE("error pushing blank frames: unlock failed: %s (%d)", strerror(-err), -err); break; } err = nativeWindow->queueBuffer(nativeWindow, buf->getNativeBuffer(), -1); if (err != NO_ERROR) { ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", strerror(-err), -err); break; } anb = NULL; } error: if (anb != NULL) { nativeWindow->cancelBuffer(nativeWindow, anb, -1); anb = NULL; } // Clean up after success or error. status_t err2 = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_CPU); if (err2 != NO_ERROR) { ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", strerror(-err2), -err2); if (err == NO_ERROR) { err = err2; } } err2 = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err2 != NO_ERROR) { ALOGE("error pushing blank frames: api_connect failed: %s (%d)", strerror(-err), -err); if (err == NO_ERROR) { err = err2; } } return err; }
PreviewRenderer::~PreviewRenderer() { native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_CPU); }
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)); }
status_t setNativeWindowSizeFormatAndUsage( ANativeWindow *nativeWindow /* nonnull */, int width, int height, int format, int rotation, int usage, bool reconnect) { status_t err = NO_ERROR; // In some cases we need to reconnect so that we can dequeue all buffers if (reconnect) { err = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err != NO_ERROR) { ALOGE("native_window_api_disconnect failed: %s (%d)", strerror(-err), -err); return err; } err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err != NO_ERROR) { ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), -err); return err; } } 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; } 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; } // Make sure to check whether either Stagefright or the video decoder // requested protected buffers. if (usage & GRALLOC_USAGE_PROTECTED) { // Check if 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; } // Check if the ANativeWindow uses hardware protected buffers. if (queuesToNativeWindow != 1 && !(consumerUsage & GRALLOC_USAGE_PROTECTED)) { ALOGE("native window could not be authenticated"); return PERMISSION_DENIED; } } 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; }