示例#1
0
void ViewBackend::commitBuffer(uint32_t handle, uint32_t width, uint32_t height)
{
    if (handle != elementHandle || width != this->width || height != this->height)
        return;

    DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0);

    VC_RECT_T srcRect, destRect;
    vc_dispmanx_rect_set(&srcRect, 0, 0, width << 16, height << 16);
    vc_dispmanx_rect_set(&destRect, 0, 0, width, height);

    vc_dispmanx_element_change_attributes(updateHandle, elementHandle, 1 << 3 | 1 << 2, 0, 0, &destRect, &srcRect, 0, DISPMANX_NO_ROTATE);

    vc_dispmanx_update_submit(updateHandle,
        [](DISPMANX_UPDATE_HANDLE_T, void* data)
        {
            auto& backend = *static_cast<ViewBackend*>(data);

            struct timeval tv;
            gettimeofday(&tv, nullptr);
            uint64_t time = tv.tv_sec * 1000 + tv.tv_usec / 1000;

            ssize_t ret = write(backend.updateFd, &time, sizeof(time));
            if (ret != sizeof(time))
                fprintf(stderr, "ViewBackend: failed to write to the update eventfd\n");
        },
        this);
}
示例#2
0
/* Warp the mouse to (x,y) */
static void
RPI_WarpMouseGlobal(int x, int y)
{
    RPI_CursorData *curdata;
    DISPMANX_UPDATE_HANDLE_T update;
    int ret;
    VC_RECT_T dst_rect;
    SDL_Mouse *mouse = SDL_GetMouse();
    
    if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
        curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
        if (curdata->element != DISPMANX_NO_HANDLE) {
            update = vc_dispmanx_update_start( 10 );
            SDL_assert( update );
            vc_dispmanx_rect_set( &dst_rect, x, y, curdata->w, curdata->h);
            ret = vc_dispmanx_element_change_attributes(
                update,
                curdata->element,
                ELEMENT_CHANGE_DEST_RECT,
                0,
                0,
                &dst_rect,
                NULL,
                DISPMANX_NO_HANDLE,
                DISPMANX_NO_ROTATE);
            SDL_assert( ret == DISPMANX_SUCCESS );
            /* Submit asynchronously, otherwise the peformance suffers a lot */
            ret = vc_dispmanx_update_submit( update, 0, NULL );
            SDL_assert( ret == DISPMANX_SUCCESS );
        }
    }    
}
static void
window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height)
{
  GST_DEBUG ("resizing window from %ux%u to %ux%u",
      window_egl->native.width, window_egl->native.height, width, height);

  if (window_egl->display) {
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    GstVideoRectangle src, dst, res;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_DISPMANX_ALPHA_T alpha =
        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0 };

    /* Center width*height frame inside dp_width*dp_height */
    src.w = width;
    src.h = height;
    src.x = src.y = 0;
    dst.w = window_egl->dp_width;
    dst.h = window_egl->dp_height;
    dst.x = dst.y = 0;
    gst_video_sink_center_rect (src, dst, &res, FALSE);

    dst_rect.x = res.x;
    dst_rect.y = res.y;
    dst_rect.width = res.w;
    dst_rect.height = res.h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = width << 16;
    src_rect.height = height << 16;

    dispman_update = vc_dispmanx_update_start (0);

    if (window_egl->native.element) {
      vc_dispmanx_element_change_attributes (dispman_update,
          window_egl->native.element, 0x00000110, 0, 0, &dst_rect, &src_rect, 0,
          0);
    } else {
      window_egl->native.element = vc_dispmanx_element_add (dispman_update,
          window_egl->display, 0, &dst_rect, 0, &src_rect,
          DISPMANX_PROTECTION_NONE, &alpha, 0, 0);
    }

    vc_dispmanx_update_submit_sync (dispman_update);

    if (GST_GL_WINDOW (window_egl)->resize)
      GST_GL_WINDOW (window_egl)->
          resize (GST_GL_WINDOW (window_egl)->resize_data, width, height);
  }

  window_egl->native.width = width;
  window_egl->native.height = height;
}
示例#4
0
void ViewBackend::Cursor::handlePointerEvent(struct wpe_input_pointer_event* event)
{
    targetClient.handlePointerEvent(event);

    DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0);

    VC_RECT_T destRect;
    vc_dispmanx_rect_set(&destRect, event->x, event->y,
        std::min<uint32_t>(cursorWidth, std::max<uint32_t>(0, displaySize.first - event->x)),
        std::min<uint32_t>(cursorHeight, std::max<uint32_t>(0, displaySize.second - event->y)));

    vc_dispmanx_element_change_attributes(updateHandle, cursorHandle, 1 << 2,
        0, 0, &destRect, nullptr, DISPMANX_NO_HANDLE, DISPMANX_NO_ROTATE);

    vc_dispmanx_update_submit_sync(updateHandle);
}
void ViewBackendBCMRPi::commitBCMBuffer(uint32_t elementHandle, uint32_t width, uint32_t height)
{
    DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0);

    m_width = width;
    m_height = height;

    VC_RECT_T srcRect, destRect;
    vc_dispmanx_rect_set(&srcRect, 0, 0, m_width << 16, m_height << 16);
    vc_dispmanx_rect_set(&destRect, 0, 0, m_width, m_height);

    vc_dispmanx_element_change_attributes(updateHandle, m_elementHandle, 1 << 3 | 1 << 2, 0, 0, &destRect, &srcRect, 0, DISPMANX_NO_ROTATE);

    vc_dispmanx_update_submit_sync(updateHandle);

    if (m_client)
        m_client->frameComplete();
}
示例#6
0
static void moveDispmanxLayer(EGLNativeWindowType window, const QPoint &pos)
{
    EGL_DISPMANX_WINDOW_T *eglWindow = static_cast<EGL_DISPMANX_WINDOW_T *>(window);
    QSize size(eglWindow->width, eglWindow->height);

    VC_RECT_T dst_rect;
    dst_rect.x = pos.x();
    dst_rect.y = pos.y();
    dst_rect.width = size.width();
    dst_rect.height = size.height();

    DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0);
    vc_dispmanx_element_change_attributes(dispman_update,
                                          eglWindow->element,
                                          ELEMENT_CHANGE_DEST_RECT /*change_flags*/,
                                          0,
                                          0,
                                          &dst_rect,
                                          NULL,
                                          0,
                                          (DISPMANX_TRANSFORM_T)0);

    vc_dispmanx_update_submit_sync(dispman_update);
}
static void *fbCursorUpdater(void *data) {
    while (1) {
        DISPMANX_UPDATE_HANDLE_T update;
        VC_RECT_T dst;
        sem_wait(&cursor.semaphore);
        pthread_mutex_lock(&cursor.mutex);
        dst.x = cursor.x;
        dst.y = cursor.y;
        dst.width = cursor.cursorWidth;
        dst.height = cursor.cursorHeight;
        pthread_mutex_unlock(&cursor.mutex);
        update = vc_dispmanx_update_start(0);
        vc_dispmanx_element_change_attributes(update,
                                              cursor.element,
                                              0x4 ,
                                              0 , 0, 
                                              &dst,
                                              0 ,
                                              0 , 0 );
        vc_dispmanx_update_submit_sync(update);
        usleep(16666); /* sleep a sixtieth of a second before moving again */
    }
    return NULL;
}
static void
window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height,
    gboolean visible)
{
  GstGLWindow *window = GST_GL_WINDOW (window_egl);

  GST_DEBUG ("resizing %s window from %ux%u to %ux%u",
      visible ? "visible" : "invisible", window_egl->native.width,
      window_egl->native.height, width, height);

  if (window_egl->display) {
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    GstVideoRectangle src, res;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    uint32_t opacity = visible ? 255 : 0;
    VC_DISPMANX_ALPHA_T alpha =
        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, opacity, 0 };

    src.w = width;
    src.h = height;
    src.x = src.y = 0;

    /* If there is no render rectangle, center the width*height frame
     *  inside dp_width*dp_height */
    if (window_egl->render_rect.w <= 0 || window_egl->render_rect.h <= 0) {
      GstVideoRectangle dst;
      dst.w = window_egl->dp_width;
      dst.h = window_egl->dp_height;
      dst.x = dst.y = 0;
      gst_video_sink_center_rect (src, dst, &res, FALSE);
    } else {
      gst_video_sink_center_rect (src, window_egl->render_rect, &res, FALSE);
    }

    dst_rect.x = res.x;
    dst_rect.y = res.y;
    dst_rect.width = res.w;
    dst_rect.height = res.h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = width << 16;
    src_rect.height = height << 16;

    dispman_update = vc_dispmanx_update_start (0);

    if (window_egl->native.element) {
      uint32_t change_flags =
          ELEMENT_CHANGE_OPACITY | ELEMENT_CHANGE_DEST_RECT |
          ELEMENT_CHANGE_SRC_RECT;
      vc_dispmanx_element_change_attributes (dispman_update,
          window_egl->native.element, change_flags, 0, opacity, &dst_rect,
          &src_rect, 0, 0);
    } else {
      window_egl->native.element = vc_dispmanx_element_add (dispman_update,
          window_egl->display, 0, &dst_rect, 0, &src_rect,
          DISPMANX_PROTECTION_NONE, &alpha, 0, 0);
    }

    vc_dispmanx_update_submit_sync (dispman_update);

    gst_gl_window_resize (window, width, height);
  }

  window_egl->native.width = width;
  window_egl->native.height = height;
}
示例#9
0
文件: gr.c 项目: CDarrow/DXX-Retro
int rpi_setup_element(int x, int y, Uint32 video_flags, int update)
{
	// this code is based on the work of Ben O'Steen
	// http://benosteen.wordpress.com/2012/04/27/using-opengl-es-2-0-on-the-raspberry-pi-without-x-windows/
	// https://github.com/benosteen/opengles-book-samples/tree/master/Raspi
	DISPMANX_UPDATE_HANDLE_T dispman_update;
	VC_RECT_T dst_rect;
	VC_RECT_T src_rect;
	VC_DISPMANX_ALPHA_T alpha_descriptor;

	uint32_t rpi_display_device=DISPMANX_ID_MAIN_LCD;
	uint32_t display_width;
	uint32_t display_height;
	int success;

	success = graphics_get_display_size(rpi_display_device, &display_width, &display_height);
	if ( success < 0 ) {
		con_printf(CON_URGENT, "Could not get RPi display size, assuming 640x480\n");
		display_width=640;
		display_height=480;
	}

	if ((uint32_t)x > display_width) {
		con_printf(CON_URGENT, "RPi: Requested width %d exceeds display width %u, scaling down!\n",
			x,display_width);
		x=(int)display_width;
	}
	if ((uint32_t)y > display_height) {
		con_printf(CON_URGENT, "RPi: Requested height %d exceeds display height %u, scaling down!\n",
			y,display_height);
		y=(int)display_height;
	}

	con_printf(CON_DEBUG, "RPi: display resolution %ux%u, game resolution: %dx%d (%s)\n", display_width, display_height, x, y, (video_flags & SDL_FULLSCREEN)?"fullscreen":"windowed");
	if (video_flags & SDL_FULLSCREEN) {
		/* scale to the full display size... */
		dst_rect.x = 0;
		dst_rect.y = 0;
		dst_rect.width = display_width;
		dst_rect.height= display_height;
	} else {
		/* TODO: we could query the position of the X11 window here
		   and try to place the ovelray exactly above that...,
		   we would have to track window movements, though ... */
		dst_rect.x = 0;
		dst_rect.y = 0;
		dst_rect.width = (uint32_t)x;
		dst_rect.height= (uint32_t)y;
	}

	src_rect.x = 0;
	src_rect.y = 0;
	src_rect.width = ((uint32_t)x)<< 16;
	src_rect.height =((uint32_t)y)<< 16;

	/* we do not want our overlay to be blended against the background */
	alpha_descriptor.flags=DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
	alpha_descriptor.opacity=0xffffffff;
	alpha_descriptor.mask=0;

	// open display, if we do not already have one ...
	if (dispman_display == DISPMANX_NO_HANDLE) {
		con_printf(CON_DEBUG, "RPi: opening display: %u\n",rpi_display_device);
		dispman_display = vc_dispmanx_display_open(rpi_display_device);
		if (dispman_display == DISPMANX_NO_HANDLE) {
			con_printf(CON_URGENT,"RPi: failed to open display: %u\n",rpi_display_device);
		}
	}

	if (dispman_element != DISPMANX_NO_HANDLE) {
		if (!update) {
			// if the element already exists, and we cannot update it, so recreate it
			rpi_destroy_element();
		}
	} else {
		// if the element does not exist, we cannot do an update
		update=0;
	}

	dispman_update = vc_dispmanx_update_start( 0 );

	if (update) {
		con_printf(CON_DEBUG, "RPi: updating display manager element\n");
		vc_dispmanx_element_change_attributes ( dispman_update, nativewindow.element,
							ELEMENT_CHANGE_DEST_RECT | ELEMENT_CHANGE_SRC_RECT,
							0 /*layer*/, 0 /*opacity*/,
							&dst_rect, &src_rect,
							0 /*mask*/, VC_IMAGE_ROT0 /*transform*/);
	} else {
		// create a new element
		con_printf(CON_DEBUG, "RPi: creating display manager element\n");
		dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
								0 /*layer*/, &dst_rect, 0 /*src*/,
								&src_rect, DISPMANX_PROTECTION_NONE,
								&alpha_descriptor, NULL /*clamp*/,
								VC_IMAGE_ROT0 /*transform*/);
		if (dispman_element == DISPMANX_NO_HANDLE) {
			con_printf(CON_URGENT,"RPi: failed to creat display manager elemenr\n");
		}
		nativewindow.element = dispman_element;
	}
	nativewindow.width = display_width;
	nativewindow.height = display_height;
	vc_dispmanx_update_submit_sync( dispman_update );

	return 0;
}