LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay* g) { unsigned pos; LLDCOLOR_TYPE color; #if GDISP_NEED_CONTROL switch(g->g.Orientation) { case GDISP_ROTATE_0: default: pos = PIXIL_POS(g, g->p.x, g->p.y); break; case GDISP_ROTATE_90: pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); break; case GDISP_ROTATE_180: pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); break; case GDISP_ROTATE_270: pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); break; } #else pos = PIXIL_POS(g, g->p.x, g->p.y); #endif #if LTDC_USE_DMA2D while(DMA2D->CR & DMA2D_CR_START); #endif color = PIXEL_ADDR(g, pos)[0]; return gdispNative2Color(color); }
LLDSPEC void gdisp_lld_draw_pixel(GDisplay* g) { unsigned pos; #if GDISP_NEED_CONTROL switch(g->g.Orientation) { case GDISP_ROTATE_0: default: pos = PIXIL_POS(g, g->p.x, g->p.y); break; case GDISP_ROTATE_90: pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); break; case GDISP_ROTATE_180: pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); break; case GDISP_ROTATE_270: pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); break; } #else pos = PIXIL_POS(g, g->p.x, g->p.y); #endif #if LTDC_USE_DMA2D while(DMA2D->CR & DMA2D_CR_START); #endif PIXEL_ADDR(g, pos)[0] = gdispColor2Native(g->p.color); }
// Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer) LLDSPEC void gdisp_lld_blit_area(GDisplay* g) { // Wait until DMA2D is ready while(DMA2D->CR & DMA2D_CR_START); // Source setup DMA2D->FGMAR = LTDC_PIXELBYTES * (g->p.y1 * g->p.x2 + g->p.x1) + (uint32_t)g->p.ptr; DMA2D->FGOR = g->p.x2 - g->p.cx; // Output setup DMA2D->OMAR = (uint32_t)PIXEL_ADDR(g, PIXIL_POS(g, g->p.x, g->p.y)); DMA2D->OOR = g->g.Width - g->p.cx; DMA2D->NLR = (g->p.cx << 16) | (g->p.cy); // Set MODE to M2M and Start the process DMA2D->CR = DMA2D_CR_MODE_M2M | DMA2D_CR_START; }
// Uses p.x,p.y p.cx,p.cy p.color LLDSPEC void gdisp_lld_fill_area(GDisplay* g) { uint32_t pos; uint32_t lineadd; uint32_t shape; // Wait until DMA2D is ready while(DMA2D->CR & DMA2D_CR_START); #if GDISP_NEED_CONTROL switch(g->g.Orientation) { case GDISP_ROTATE_0: default: pos = PIXIL_POS(g, g->p.x, g->p.y); lineadd = g->g.Width - g->p.cx; shape = (g->p.cx << 16) | (g->p.cy); break; case GDISP_ROTATE_90: pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-g->p.cx); lineadd = g->g.Height - g->p.cy; shape = (g->p.cy << 16) | (g->p.cx); break; case GDISP_ROTATE_180: pos = PIXIL_POS(g, g->g.Width-g->p.x-g->p.cx, g->g.Height-g->p.y-g->p.cy); lineadd = g->g.Width - g->p.cx; shape = (g->p.cx << 16) | (g->p.cy); break; case GDISP_ROTATE_270: pos = PIXIL_POS(g, g->g.Height-g->p.y-g->p.cy, g->p.x); lineadd = g->g.Height - g->p.cy; shape = (g->p.cy << 16) | (g->p.cx); break; } #else pos = PIXIL_POS(g, g->p.x, g->p.y); lineadd = g->g.Width - g->p.cx; shape = (g->p.cx << 16) | (g->p.cy); #endif // Start the DMA2D DMA2D->OMAR = (uint32_t)PIXEL_ADDR(g, pos); DMA2D->OOR = lineadd; DMA2D->NLR = shape; DMA2D->OCOLR = (uint32_t)(gdispColor2Native(g->p.color)); DMA2D->CR = DMA2D_CR_MODE_R2M | DMA2D_CR_START; }
static void rf_host_fbupdate_raw(void) { #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #endif fbs_spool_data(cur_slot->readbuf, cur_rect.w * sizeof(CARD32)); if (++rect_cur_row < cur_rect.h) { /* Read next row */ CARD32 *dst = PIXEL_ADDR(g_framebuffer, g_fb_width, g_fb_height, cur_rect.x, cur_rect.y + rect_cur_row); aio_setread(rf_host_fbupdate_raw, dst, cur_rect.w * sizeof(CARD32)); } else { /* Done with this rectangle */ fbupdate_rect_done(); } }
static void rf_host_fbupdate_recthdr(void) { HOST_SLOT *hs = (HOST_SLOT *)cur_slot; #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #endif cur_rect.x = buf_get_CARD16(cur_slot->readbuf); cur_rect.y = buf_get_CARD16(&cur_slot->readbuf[2]); cur_rect.w = buf_get_CARD16(&cur_slot->readbuf[4]); cur_rect.h = buf_get_CARD16(&cur_slot->readbuf[6]); cur_rect.enc = buf_get_CARD32(&cur_slot->readbuf[8]); fbs_spool_data(cur_slot->readbuf, 12); /* Handle LastRect "encoding" first */ if (cur_rect.enc == RFB_ENCODING_LASTRECT) { log_write(LL_DEBUG, "LastRect marker received from the host"); cur_rect.x = cur_rect.y = 0; rect_count = 1; fbupdate_rect_done(); return; } /* Ignore zero-size rectangles */ if (cur_rect.h == 0 || cur_rect.w == 0) { log_write(LL_WARN, "Zero-size rectangle %dx%d at %d,%d (ignoring)", (int)cur_rect.w, (int)cur_rect.h, (int)cur_rect.x, (int)cur_rect.y); fbupdate_rect_done(); return; } /* Handle NewFBSize "encoding", as a special case */ if (cur_rect.enc == RFB_ENCODING_NEWFBSIZE) { log_write(LL_INFO, "New host desktop geometry: %dx%d", (int)cur_rect.w, (int)cur_rect.h); g_screen_info.width = hs->fb_width = cur_rect.w; g_screen_info.height = hs->fb_height = cur_rect.h; /* Reallocate the framebuffer if necessary */ if (!alloc_framebuffer(hs->fb_width, hs->fb_height)) { aio_close(1); return; } cur_rect.x = cur_rect.y = 0; /* NewFBSize is always the last rectangle regardless of rect_count */ rect_count = 1; fbupdate_rect_done(); return; } /* Prevent overflow of the framebuffer */ if (cur_rect.x >= g_fb_width || cur_rect.x + cur_rect.w > g_fb_width || cur_rect.y >= g_fb_height || cur_rect.y + cur_rect.h > g_fb_height) { log_write(LL_ERROR, "Rectangle out of framebuffer bounds: %dx%d at %d,%d", (int)cur_rect.w, (int)cur_rect.h, (int)cur_rect.x, (int)cur_rect.y); aio_close(0); return; } /* Ok, now the rectangle seems correct */ log_write(LL_DEBUG, "Receiving rectangle %dx%d at %d,%d", (int)cur_rect.w, (int)cur_rect.h, (int)cur_rect.x, (int)cur_rect.y); switch(cur_rect.enc) { case RFB_ENCODING_RAW: log_write(LL_DEBUG, "Receiving raw data, expecting %d byte(s)", cur_rect.w * cur_rect.h * sizeof(CARD32)); rect_cur_row = 0; aio_setread(rf_host_fbupdate_raw, PIXEL_ADDR(g_framebuffer, g_fb_width, g_fb_height, cur_rect.x, cur_rect.y), cur_rect.w * sizeof(CARD32)); break; case RFB_ENCODING_COPYRECT: log_write(LL_DEBUG, "Receiving CopyRect instruction"); aio_setread(rf_host_copyrect, NULL, 4); break; case RFB_ENCODING_HEXTILE: log_write(LL_DEBUG, "Receiving Hextile-encoded data"); setread_decode_hextile(&cur_rect); break; case RFB_ENCODING_TIGHT: log_write(LL_DEBUG, "Receiving Tight-encoded data"); setread_decode_tight(&cur_rect); break; default: log_write(LL_ERROR, "Unknown encoding: 0x%08lX", (unsigned long)cur_rect.enc); aio_close(0); } }