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); }
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"); }
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; }
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; }
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; }
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; }
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; }
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()); }
void egl_window_surface_t::setSwapInterval(int interval) { nativeWindow->setSwapInterval(nativeWindow, interval); }
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)); }
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; }