/** * \brief Implementation of surface:set_opacity(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::surface_api_set_opacity(lua_State* l) { Surface& surface = check_surface(l, 1); int opacity = luaL_checkint(l, 2); surface.set_opacity(opacity); return 0; }
/** * \brief Implementation of surface:get_size(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::surface_api_get_size(lua_State* l) { Surface& surface = check_surface(l, 1); lua_pushinteger(l, surface.get_width()); lua_pushinteger(l, surface.get_height()); return 2; }
/** * @brief Implementation of surface:get_transparency_color(). * @param l The Lua context that is calling this function. * @return Number of values to return to Lua. */ int LuaContext::surface_api_get_transparency_color(lua_State* l) { Surface& surface = check_surface(l, 1); const Color& color = surface.get_transparency_color(); push_color(l, color); return 1; }
/** * \brief Implementation of surface:get_size(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_get_size(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Surface& surface = *check_surface(l, 1); lua_pushinteger(l, surface.get_width()); lua_pushinteger(l, surface.get_height()); return 2; }); }
/** * \brief Implementation of surface:get_pixels(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_get_pixels(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Surface& surface = *check_surface(l, 1); // TODO optional parameters x, y, width, height push_string(l, surface.get_pixels()); return 1; }); }
/** * \brief Implementation of drawable:draw(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::drawable_api_draw(lua_State* l) { Drawable& drawable = check_drawable(l, 1); Surface& dst_surface = check_surface(l, 2); int x = luaL_optint(l, 3, 0); int y = luaL_optint(l, 4, 0); drawable.draw(dst_surface, x, y); return 0; }
/** * \brief Implementation of surface:clear(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_clear(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Surface& surface = *check_surface(l, 1); surface.clear(); return 0; }); }
/** * \brief Implementation of surface:set_opacity(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_set_opacity(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Surface& surface = *check_surface(l, 1); uint8_t opacity = (uint8_t) LuaTools::check_int(l, 2); surface.set_opacity(opacity); return 0; }); }
/** * \brief Implementation of surface:get_opacity(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_get_opacity(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { const Surface& surface = *check_surface(l, 1); uint8_t opacity = surface.get_opacity(); lua_pushinteger(l, opacity); return 1; }); }
/** * \brief Implementation of drawable:draw(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::drawable_api_draw(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Drawable& drawable = *check_drawable(l, 1); SurfacePtr dst_surface = check_surface(l, 2); int x = LuaTools::opt_int(l, 3, 0); int y = LuaTools::opt_int(l, 4, 0); drawable.draw(dst_surface, x, y); return 0; }); }
/** * \brief Implementation of drawable:draw_region(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::drawable_api_draw_region(lua_State* l) { Drawable& drawable = check_drawable(l, 1); Rectangle region( luaL_checkint(l, 2), luaL_checkint(l, 3), luaL_checkint(l, 4), luaL_checkint(l, 5) ); Surface& dst_surface = check_surface(l, 6); Rectangle dst_position( luaL_optint(l, 7, 0), luaL_optint(l, 8, 0) ); drawable.draw_region(region, dst_surface, dst_position); return 0; }
/** * \brief Implementation of surface:fill_color(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::surface_api_fill_color(lua_State* l) { Surface& surface = check_surface(l, 1); Color color = check_color(l, 2); if (lua_gettop(l) >= 3) { int x = luaL_checkint(l, 3); int y = luaL_checkint(l, 4); int width = luaL_checkint(l, 5); int height = luaL_checkint(l, 6); Rectangle where(x, y, width, height); surface.fill_with_color(color, where); } else { surface.fill_with_color(color); } return 0; }
/** * \brief Implementation of drawable:draw_region(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::drawable_api_draw_region(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Drawable& drawable = *check_drawable(l, 1); Rectangle region = { LuaTools::check_int(l, 2), LuaTools::check_int(l, 3), LuaTools::check_int(l, 4), LuaTools::check_int(l, 5) }; SurfacePtr dst_surface = check_surface(l, 6); Point dst_position = { LuaTools::opt_int(l, 7, 0), LuaTools::opt_int(l, 8, 0) }; drawable.draw_region(region, dst_surface, dst_position); return 0; }); }
/** * \brief Implementation of surface:fill_color(). * \param l The Lua context that is calling this function. * \return Number of values to return to Lua. */ int LuaContext::surface_api_fill_color(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { Surface& surface = *check_surface(l, 1); Color color = LuaTools::check_color(l, 2); if (lua_gettop(l) >= 3) { int x = LuaTools::check_int(l, 3); int y = LuaTools::check_int(l, 4); int width = LuaTools::check_int(l, 5); int height = LuaTools::check_int(l, 6); Rectangle where(x, y, width, height); surface.fill_with_color(color, where); } else { surface.fill_with_color(color); } return 0; }); }
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { GrProxyProvider* proxyProvider = ctxInfo.grContext()->priv().proxyProvider(); GrContext* context = ctxInfo.grContext(); GrResourceProvider* resourceProvider = context->priv().resourceProvider(); GrGpu* gpu = context->priv().getGpu(); const GrCaps& caps = *context->priv().caps(); static const int kWidthHeight = 100; for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) { for (auto colorType : { kAlpha_8_SkColorType, kRGBA_8888_SkColorType, kRGBA_1010102_SkColorType }) { // External on-screen render target. // Tests wrapBackendRenderTarget with a GrBackendRenderTarget // Our test-only function that creates a backend render target doesn't currently support // sample counts :(. if (ctxInfo.grContext()->colorTypeSupportedAsSurface(colorType)) { GrBackendRenderTarget backendRT = gpu->createTestingOnlyBackendRenderTarget( kWidthHeight, kWidthHeight, SkColorTypeToGrColorType(colorType)); sk_sp<GrSurfaceProxy> sProxy( proxyProvider->wrapBackendRenderTarget(backendRT, origin, nullptr, nullptr)); check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight, backendRT.pixelConfig(), SkBudgeted::kNo); static constexpr int kExpectedNumSamples = 1; check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(), kExpectedNumSamples, SkBackingFit::kExact, caps.maxWindowRectangles()); gpu->deleteTestingOnlyBackendRenderTarget(backendRT); } for (auto numSamples : {1, 4}) { GrPixelConfig config = SkColorType2GrPixelConfig(colorType); SkASSERT(kUnknown_GrPixelConfig != config); int supportedNumSamples = caps.getRenderTargetSampleCount(numSamples, config); if (!supportedNumSamples) { continue; } // Test wrapping FBO 0 (with made up properties). This tests sample count and the // special case where FBO 0 doesn't support window rectangles. if (GrBackendApi::kOpenGL == ctxInfo.backend()) { GrGLFramebufferInfo fboInfo; fboInfo.fFBOID = 0; fboInfo.fFormat = GR_GL_RGBA8; static constexpr int kStencilBits = 8; GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples, kStencilBits, fboInfo); backendRT.setPixelConfig(config); sk_sp<GrSurfaceProxy> sProxy( proxyProvider->wrapBackendRenderTarget(backendRT, origin, nullptr, nullptr)); check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight, backendRT.pixelConfig(), SkBudgeted::kNo); check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(), supportedNumSamples, SkBackingFit::kExact, 0); } // Tests wrapBackendRenderTarget with a GrBackendTexture { GrBackendTexture backendTex = context->createBackendTexture(kWidthHeight, kWidthHeight, colorType, GrMipMapped::kNo, GrRenderable::kYes); sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTextureAsRenderTarget( backendTex, origin, supportedNumSamples); if (!sProxy) { context->deleteBackendTexture(backendTex); continue; // This can fail on Mesa } check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight, backendTex.pixelConfig(), SkBudgeted::kNo); check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(), supportedNumSamples, SkBackingFit::kExact, caps.maxWindowRectangles()); context->deleteBackendTexture(backendTex); } // Tests wrapBackendTexture that is only renderable { GrBackendTexture backendTex = context->createBackendTexture(kWidthHeight, kWidthHeight, colorType, GrMipMapped::kNo, GrRenderable::kYes); sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapRenderableBackendTexture( backendTex, origin, supportedNumSamples, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, nullptr, nullptr); if (!sProxy) { context->deleteBackendTexture(backendTex); continue; // This can fail on Mesa } check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight, backendTex.pixelConfig(), SkBudgeted::kNo); check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(), supportedNumSamples, SkBackingFit::kExact, caps.maxWindowRectangles()); context->deleteBackendTexture(backendTex); } // Tests wrapBackendTexture that is only textureable { // Internal offscreen texture GrBackendTexture backendTex = context->createBackendTexture(kWidthHeight, kWidthHeight, colorType, GrMipMapped::kNo, GrRenderable::kNo); sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTexture( backendTex, origin, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRead_GrIOType); if (!sProxy) { context->deleteBackendTexture(backendTex); continue; } check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight, backendTex.pixelConfig(), SkBudgeted::kNo); check_texture(reporter, resourceProvider, sProxy->asTextureProxy(), SkBackingFit::kExact); context->deleteBackendTexture(backendTex); } } } } }
static int dovefb_switch_buff(struct fb_info *fi) { struct dovefb_layer_info *dfli = fi->par; int i = 0; struct _sOvlySurface *pOvlySurface = 0; unsigned long startaddr; int fbid; /* First check if we have a faster path */ if (dfli->vid_ovly_phys_addr_y) { /* Found a frame that should be presented now */ writel(dfli->vid_ovly_phys_addr_y, dfli->reg_base + LCD_SPU_DMA_START_ADDR_Y0); writel(dfli->vid_ovly_phys_addr_u, dfli->reg_base + LCD_SPU_DMA_START_ADDR_U0); writel(dfli->vid_ovly_phys_addr_v, dfli->reg_base + LCD_SPU_DMA_START_ADDR_V0); dfli->vid_ovly_phys_addr_y = 0; return 0; } /* * Find the latest frame. */ for (i = (MAX_QUEUE_NUM-1); i >= 0; i--) { if (freeBufList[i]) { pOvlySurface = (struct _sOvlySurface *)freeBufList[i]; break; } } if (!pOvlySurface) { /*pr_debug("********Oops: pOvlySurface" " is NULL!!!!\n\n");*/ return -1; } startaddr = (unsigned long)pOvlySurface->videoBufferAddr.startAddr; fbid = (int)pOvlySurface->videoBufferAddr.frameID; /* * Got new frame? */ if (dfli->new_addr != startaddr) { /* * Collect expired frame to list. */ collectFreeBuf(filterBufList, freeBufList, (i)); } /* * Update new surface. */ if (check_surface(fi, pOvlySurface->videoMode, &pOvlySurface->viewPortInfo, &pOvlySurface->viewPortOffset, &pOvlySurface->videoBufferAddr)) { dovefb_ovly_set_par(fi); dfli->cur_fbid = fbid; } return 0; }
static int dovefb_ovly_ioctl(struct fb_info *fi, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct dovefb_layer_info *dfli = fi->par; u32 x; int vmode = 0; int gfx_on = 1; int vid_on = 1; int interpolation = 0; switch (cmd) { case DOVEFB_IOCTL_WAIT_VSYNC: wait_for_vsync(dfli); break; case DOVEFB_IOCTL_GET_VIEWPORT_INFO: return copy_to_user(argp, &dfli->surface.viewPortInfo, sizeof(struct _sViewPortInfo)) ? -EFAULT : 0; case DOVEFB_IOCTL_SET_VIEWPORT_INFO: mutex_lock(&dfli->access_ok); if (copy_from_user(&gViewPortInfo, argp, sizeof(gViewPortInfo))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } if (check_surface(fi, -1, &gViewPortInfo, 0, 0)) dovefb_ovly_set_par(fi); mutex_unlock(&dfli->access_ok); break; case DOVEFB_IOCTL_SET_VIDEO_MODE: /* * Get data from user space. */ if (copy_from_user(&vmode, argp, sizeof(vmode))) return -EFAULT; if (check_surface(fi, vmode, 0, 0, 0)) dovefb_ovly_set_par(fi); break; case DOVEFB_IOCTL_GET_VIDEO_MODE: return copy_to_user(argp, &dfli->surface.videoMode, sizeof(u32)) ? -EFAULT : 0; case DOVEFB_IOCTL_CREATE_VID_BUFFER: { struct _sOvlySurface OvlySurface; mutex_lock(&dfli->access_ok); if (copy_from_user(&OvlySurface, argp, sizeof(struct _sOvlySurface))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } /* Request a video buffer. */ dovefb_ovly_create_surface(&OvlySurface); if (copy_to_user(argp, &OvlySurface, sizeof(struct _sOvlySurface))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } mutex_unlock(&dfli->access_ok); break; } case DOVEFB_IOCTL_FLIP_VID_BUFFER: { struct _sOvlySurface *surface = 0; u8 *start_addr, *input_data, *dst_addr; u32 length; surface = kmalloc(sizeof(struct _sOvlySurface), GFP_KERNEL); /* Get user-mode data. */ if (copy_from_user(surface, argp, sizeof(struct _sOvlySurface))) { kfree(surface); return -EFAULT; } mutex_lock(&dfli->access_ok); length = surface->videoBufferAddr.length; dst_addr = dfli->surface.videoBufferAddr.startAddr; start_addr = surface->videoBufferAddr.startAddr; input_data = surface->videoBufferAddr.inputData; /* * Has DMA addr? */ if (start_addr && (!input_data)) { if (0 != addFreeBuf(freeBufList, (u8 *)surface)) { pr_debug("Error: addFreeBuf()\n"); mutex_unlock(&dfli->access_ok); kfree(surface); return -EFAULT; } else { /* pr_debug("addFreeBuf(0x%08x) ok.\n", start_addr); */ } } else { if (check_surface(fi, surface->videoMode, &surface->viewPortInfo, &surface->viewPortOffset, &surface->videoBufferAddr)) dovefb_ovly_set_par(fi); /* copy buffer */ if (input_data) { wait_for_vsync(dfli); /* if support hw DMA, replace this. */ if (copy_from_user(dfli->fb_start, input_data, length)) { mutex_unlock(&dfli->access_ok); kfree(surface); return -EFAULT; } mutex_unlock(&dfli->access_ok); kfree(surface); return 0; } kfree(surface); #if 0 /* * Fix me: Currently not implemented yet. * Application allocate a physical contiguous * buffer and pass it into driver. Here is to * update fb's info to new buffer and free * old buffer. */ if (start_addr) { if (dfli->mem_status) free_pages( (unsigned long)dfli->fb_start, get_order(dfli->fb_size)); else dma_free_writecombine(dfli->dev, dfli->fb_size, dfli->fb_start, dfli->fb_start_dma); dfli->fb_start = __va(start_addr); dfli->fb_size = length; dfli->fb_start_dma = (dma_addr_t)__pa(dfli->fb_start); dfli->mem_status = 1; fi->fix.smem_start = dfli->fb_start_dma; fi->fix.smem_len = dfli->fb_size; fi->screen_base = dfli->fb_start; fi->screen_size = dfli->fb_size; } #endif } mutex_unlock(&dfli->access_ok); return 0; } case DOVEFB_IOCTL_GET_FREELIST: { mutex_lock(&dfli->access_ok); if (copy_to_user(argp, filterBufList, MAX_QUEUE_NUM*sizeof(u8 *))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } clearFreeBuf(filterBufList, RESET_BUF); mutex_unlock(&dfli->access_ok); return 0; } case DOVEFB_IOCTL_GET_BUFF_ADDR: { return copy_to_user(argp, &dfli->surface.videoBufferAddr, sizeof(struct _sVideoBufferAddr)) ? -EFAULT : 0; } case DOVEFB_IOCTL_SET_VID_OFFSET: mutex_lock(&dfli->access_ok); if (copy_from_user(&gViewPortOffset, argp, sizeof(gViewPortOffset))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } if (check_surface(fi, -1, 0, &gViewPortOffset, 0)) dovefb_ovly_set_par(fi); mutex_unlock(&dfli->access_ok); break; case DOVEFB_IOCTL_GET_VID_OFFSET: return copy_to_user(argp, &dfli->surface.viewPortOffset, sizeof(struct _sViewPortOffset)) ? -EFAULT : 0; case DOVEFB_IOCTL_SET_MEMORY_TOGGLE: break; case DOVEFB_IOCTL_SET_COLORKEYnALPHA: if (copy_from_user(&dfli->ckey_alpha, argp, sizeof(struct _sColorKeyNAlpha))) return -EFAULT; dovefb_ovly_set_colorkeyalpha(dfli); break; case DOVEFB_IOCTL_GET_COLORKEYnALPHA: if (copy_to_user(argp, &dfli->ckey_alpha, sizeof(struct _sColorKeyNAlpha))) return -EFAULT; break; case DOVEFB_IOCTL_SWITCH_VID_OVLY: if (copy_from_user(&vid_on, argp, sizeof(int))) return -EFAULT; if (0 == vid_on) { x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) & ~CFG_DMA_ENA_MASK; writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0); } else { x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) | CFG_DMA_ENA(0x1); writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0); /* Enable VID & VSync. */ x = readl(dfli->reg_base + SPU_IRQ_ENA) | DOVEFB_VID_INT_MASK | DOVEFB_VSYNC_INT_MASK; writel(x, dfli->reg_base + SPU_IRQ_ENA); } break; case DOVEFB_IOCTL_SWITCH_GRA_OVLY: if (copy_from_user(&gfx_on, argp, sizeof(int))) return -EFAULT; if (0 == gfx_on) { x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) & ~CFG_GRA_ENA_MASK; writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0); } else { x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) | CFG_GRA_ENA(0x1); writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0); } break; case DOVEFB_IOCTL_GET_FBID: mutex_lock(&dfli->access_ok); if (copy_to_user(argp, &dfli->cur_fbid, sizeof(unsigned int))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } mutex_unlock(&dfli->access_ok); break; case DOVEFB_IOCTL_GET_SRC_MODE: mutex_lock(&dfli->access_ok); if (copy_to_user(argp, &dfli->src_mode, sizeof(int))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } mutex_unlock(&dfli->access_ok); break; case DOVEFB_IOCTL_SET_SRC_MODE: mutex_lock(&dfli->access_ok); if (copy_from_user(&dfli->src_mode, argp, sizeof(int))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } if (SHM_NORMAL == dfli->src_mode) { int i; /* * Recycle all video buffer. */ /* 1. collect freelist buffer */ for (i = (MAX_QUEUE_NUM-1); i >= 0; i--) { if (freeBufList[i]) break; } collectFreeBuf(filterBufList, freeBufList, (i)); /* 2. Recycle current frame to filter list. */ for (i = 0; i < MAX_QUEUE_NUM; i++) { if (!filterBufList[i]) filterBufList[i] = (u8 *)dfli->new_addr; } /* clear and reset related resource. */ clearFreeBuf(freeBufList, RESET_BUF|FREE_ENTRY); dfli->new_addr = 0; dfli->cur_fbid = 0; memset(dfli->fb_start, 0, dfli->fb_size); } mutex_unlock(&dfli->access_ok); break; case DOVEFB_IOCTL_GET_FBPA: { struct shm_private_info info; int index; if (copy_from_user(&info, argp, sizeof(struct shm_private_info))) return -EFAULT; /* which frame want to find. */ index = info.fbid; /* calc physical address. */ info.fb_pa = (unsigned long)(dfli->fb_start_dma+ (index*info.width*info.height*MAX_YUV_PIXEL)); if (copy_to_user(argp, &info, sizeof(struct shm_private_info))) return -EFAULT; break; } case DOVEFB_IOCTL_NEXT_FRAME_PRESENT: { unsigned int phy_addr[3]; mutex_lock(&dfli->access_ok); if (copy_from_user(&phy_addr, argp, 3*sizeof(unsigned int))) { mutex_unlock(&dfli->access_ok); return -EFAULT; } mutex_unlock(&dfli->access_ok); dfli->vid_ovly_phys_addr_y = phy_addr[0]; dfli->vid_ovly_phys_addr_u = phy_addr[1]; dfli->vid_ovly_phys_addr_v = phy_addr[2]; break; } case DOVEFB_IOCTL_SET_INTERPOLATION_MODE: /* * Get data from user space. */ if (copy_from_user(&interpolation, argp, sizeof(interpolation))) return -EFAULT; if ((interpolation == 0) || (interpolation == 3)) writel(CFG_VSC_LINEAR(interpolation) | (readl(dfli->reg_base + SPU_IOPAD_CONTROL) & !CFG_VSC_LINEAR_MASK), dfli->reg_base + SPU_IOPAD_CONTROL); break; default: pr_debug("ioctl_ovly(0x%x) No match.\n", cmd); break; } return 0; }
static int pxa168fb_ovly_ioctl(struct fb_info *fi, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct pxa168fb_info *fbi = (struct pxa168fb_info *)fi->par; struct pxa168fb_mach_info *mi = fbi->dev->platform_data; int vid_on = 1; int val = 0, mask = 0; unsigned char param; int blendval = 0; int res, tmp; int ret = 0; unsigned long flags; #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG debug_identify_called_ioctl(fi, cmd, arg); #endif switch (cmd) { case FB_IOCTL_CLEAR_FRAMEBUFFER: if (!mi->mmap) return -EINVAL; pxa168fb_clear_framebuffer(fi); return 0; break; case FB_IOCTL_WAIT_VSYNC: param = (arg & 0x3); wait_for_vsync(fbi, param); break; case FB_IOCTL_GET_VIEWPORT_INFO:/*if rotate 90/270, w/h swap*/ mutex_lock(&fbi->access_ok); if (fbi->surface.viewPortInfo.rotation == 90 || fbi->surface.viewPortInfo.rotation == 270) { tmp = fbi->surface.viewPortInfo.srcWidth; fbi->surface.viewPortInfo.srcWidth = fbi->surface.viewPortInfo.srcHeight; fbi->surface.viewPortInfo.srcHeight = tmp; fbi->surface.viewPortInfo.rotation = 360 - fbi->surface.viewPortInfo.rotation; } res = copy_to_user(argp, &fbi->surface.viewPortInfo, sizeof(struct _sViewPortInfo)) ? -EFAULT : 0; if (fbi->surface.viewPortInfo.rotation == 90 || fbi->surface.viewPortInfo.rotation == 270) { tmp = fbi->surface.viewPortInfo.srcWidth; fbi->surface.viewPortInfo.srcWidth = fbi->surface.viewPortInfo.srcHeight; fbi->surface.viewPortInfo.srcHeight = tmp; fbi->surface.viewPortInfo.rotation = 360 - fbi->surface.viewPortInfo.rotation; } mutex_unlock(&fbi->access_ok); return res; case FB_IOCTL_SET_VIEWPORT_INFO:/*if rotate 90/270, w/h swap*/ mutex_lock(&fbi->access_ok); memset(&gOvlySurface, 0, sizeof(gOvlySurface)); gOvlySurface.videoMode = -1; if (copy_from_user(&gOvlySurface.viewPortInfo, argp, sizeof(gOvlySurface.viewPortInfo))) { mutex_unlock(&fbi->access_ok); return -EFAULT; } if (unsupport_format(fbi, gOvlySurface.viewPortInfo, -1)) { mutex_unlock(&fbi->access_ok); return -EFAULT; } gOvlySurface.viewPortInfo.rotation = (360 - gOvlySurface.viewPortInfo.rotation) % 360; if (gOvlySurface.viewPortInfo.rotation == 90 || gOvlySurface.viewPortInfo.rotation == 270) { tmp = gOvlySurface.viewPortInfo.srcWidth; gOvlySurface.viewPortInfo.srcWidth = gOvlySurface.viewPortInfo.srcHeight; gOvlySurface.viewPortInfo.srcHeight = tmp; } ret = check_surface(fi, &gOvlySurface); if (ret > 0) { pxa168fb_set_par(fi); ret = 0; } else if (ret < 0) { pr_err("fbi %d (line %d): vid %d, check surface" "return error\n", fbi->id, __LINE__, fbi->vid); ret = -EFAULT; } mutex_unlock(&fbi->access_ok); return ret; break; case FB_IOCTL_SET_VIDEO_MODE: /* * Get data from user space. */ memset(&gOvlySurface, 0, sizeof(gOvlySurface)); if (copy_from_user(&gOvlySurface.videoMode, argp, sizeof(gOvlySurface.videoMode))) return -EFAULT; if (unsupport_format(fbi, gOvlySurface.viewPortInfo, gOvlySurface.videoMode)) return -EFAULT; ret = check_surface(fi, &gOvlySurface); if (ret > 0) { pxa168fb_set_par(fi); ret = 0; } else if (ret < 0) { pr_err("fbi %d (line %d): vid %d, check surface" "return error\n", fbi->id, __LINE__, fbi->vid); ret = -EFAULT; } return ret; break; case FB_IOCTL_GET_VIDEO_MODE: return copy_to_user(argp, &fbi->surface.videoMode, sizeof(u32)) ? -EFAULT : 0; case FB_IOCTL_FLIP_VID_BUFFER: return flip_buffer(fi, arg); case FB_IOCTL_GET_FREELIST: return get_freelist(fi, arg); case FB_IOCTL_FLIP_VSYNC: return flip_buffer_vsync(fi, arg); case FB_IOCTL_GET_BUFF_ADDR: { return copy_to_user(argp, &fbi->surface.videoBufferAddr, sizeof(struct _sVideoBufferAddr)) ? -EFAULT : 0; } case FB_IOCTL_SET_VID_OFFSET: mutex_lock(&fbi->access_ok); memset(&gOvlySurface, 0, sizeof(gOvlySurface)); gOvlySurface.videoMode = -1; if (copy_from_user(&gOvlySurface.viewPortOffset, argp, sizeof(gOvlySurface.viewPortOffset))) { mutex_unlock(&fbi->access_ok); return -EFAULT; } ret = check_surface(fi, &gOvlySurface); if (ret > 0) { pxa168fb_set_par(fi); ret = 0; } else if (ret < 0) { pr_err("fbi %d (line %d): vid %d, check surface" "return error\n", fbi->id, __LINE__, fbi->vid); ret = -EFAULT; } mutex_unlock(&fbi->access_ok); return ret; break; case FB_IOCTL_GET_VID_OFFSET: return copy_to_user(argp, &fbi->surface.viewPortOffset, sizeof(struct _sViewPortOffset)) ? -EFAULT : 0; case FB_IOCTL_SET_SURFACE: { mutex_lock(&fbi->access_ok); /* Get user-mode data. */ if (copy_from_user(&fbi->surface_bak, argp, sizeof(struct _sOvlySurface))) { mutex_unlock(&fbi->access_ok); return -EFAULT; } fbi->surface_set = 1; mutex_unlock(&fbi->access_ok); return 0; } case FB_IOCTL_GET_SURFACE: { mutex_lock(&fbi->access_ok); if (fbi->surface_set) { ret = copy_to_user(argp, &fbi->surface_bak, sizeof(struct _sOvlySurface)); } else { ret = copy_to_user(argp, &fbi->surface, sizeof(struct _sOvlySurface)); } ret = (ret ? -EFAULT : 0); mutex_unlock(&fbi->access_ok); return ret; } case FB_IOCTL_SET_COLORKEYnALPHA: if (copy_from_user(&fbi->ckey_alpha, argp, sizeof(struct _sColorKeyNAlpha))) return -EFAULT; pxa168fb_ovly_set_colorkeyalpha(fbi); break; case FB_IOCTL_GET_COLORKEYnALPHA: if (copy_to_user(argp, &fbi->ckey_alpha, sizeof(struct _sColorKeyNAlpha))) return -EFAULT; break; case FB_IOCTL_SWITCH_VID_OVLY: if (copy_from_user(&vid_on, argp, sizeof(int))) return -EFAULT; spin_lock_irqsave(&fbi->var_lock, flags); mask = CFG_DMA_ENA_MASK; fbi->dma_on = vid_on ? 1 : 0; val = CFG_DMA_ENA(check_modex_active(fbi)); if (!val && gfx_info.fbi[0]->active) { pxa688_vdma_release(fbi->id, fbi->vid); /* switch off, disable DMA */ dma_ctrl_set(fbi->id, 0, mask, val); } else if (list_empty(&fbi->buf_waitlist.dma_queue) && !fbi->buf_current) /* switch on, but no buf flipped, return error */ ; /* ret = -EAGAIN; */ printk(KERN_DEBUG "SWITCH_VID_OVLY fbi %d dma_on %d," " val %d, waitlist empty %d buf_current %p, ret %d\n", fbi->id, fbi->dma_on, val, list_empty(&fbi->buf_waitlist.dma_queue), fbi->buf_current, ret); pxa688fb_vsmooth_set(fbi->id, 1, vid_vsmooth & vid_on); spin_unlock_irqrestore(&fbi->var_lock, flags); return ret; break; case FB_IOCTL_SWAP_VIDEO_RED_BLUE: param = (arg & 0x1); dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPRB_MASK, CFG_DMA_SWAPRB(param)); return 0; break; case FB_IOCTL_SWAP_VIDEO_U_V: param = (arg & 0x1); dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPUV_MASK, CFG_DMA_SWAPUV(param)); return 0; break; case FB_IOCTL_SWAP_VIDEO_Y_UV: param = (arg & 0x1); dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPYU_MASK, CFG_DMA_SWAPYU(param)); return 0; break; case FB_IOCTL_PUT_VIDEO_ALPHABLEND: /* * This puts the blending control to the Video layer. */ mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK; val = CFG_ALPHA_MODE(0) | CFG_ALPHA(0xff); dma_ctrl_set(fbi->id, 1, mask, val); return 0; break; case FB_IOCTL_PUT_GLOBAL_ALPHABLEND: /* * The userspace application can specify a byte value for the * amount of global blend between the video layer and thei * graphic layer. * * The alpha blending is per the formula below: * P = (V[P] * blendval/255) + (G[P] * (1 - blendval/255)) * where: P = Pixel value, V = Video Layer, * and G = Graphic Layer */ blendval = (arg & 0xff); mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK; val = CFG_ALPHA_MODE(2) | CFG_ALPHA(blendval); dma_ctrl_set(fbi->id, 1, mask, val); return 0; break; case FB_IOCTL_PUT_GRAPHIC_ALPHABLEND: /* * This puts the blending back to the default mode of allowing * the graphic layer to do pixel level blending. */ mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK; val = CFG_ALPHA_MODE(1) | CFG_ALPHA(0x0); dma_ctrl_set(fbi->id, 1, mask, val); return 0; break; default: break; } return 0; }
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { GrProxyProvider* proxyProvider = ctxInfo.grContext()->priv().proxyProvider(); GrResourceProvider* resourceProvider = ctxInfo.grContext()->priv().resourceProvider(); const GrCaps& caps = *ctxInfo.grContext()->priv().caps(); int attempt = 0; // useful for debugging for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) { for (auto widthHeight : { 100, 128, 1048576 }) { for (auto config : { kAlpha_8_GrPixelConfig, kRGB_565_GrPixelConfig, kRGBA_8888_GrPixelConfig, kRGBA_1010102_GrPixelConfig, kRGB_ETC1_GrPixelConfig }) { for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) { for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) { for (auto numSamples : {1, 4, 16, 128}) { // We don't have recycling support for compressed textures if (GrPixelConfigIsCompressed(config) && SkBackingFit::kApprox == fit) { continue; } GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = widthHeight; desc.fHeight = widthHeight; desc.fConfig = config; desc.fSampleCnt = numSamples; GrSRGBEncoded srgbEncoded; GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded); const GrBackendFormat format = caps.getBackendFormatFromGrColorType(colorType, srgbEncoded); { sk_sp<GrTexture> tex; if (SkBackingFit::kApprox == fit) { tex = resourceProvider->createApproxTexture( desc, GrResourceProvider::Flags::kNoPendingIO); } else { tex = resourceProvider->createTexture( desc, budgeted, GrResourceProvider::Flags::kNoPendingIO); } sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format, desc, origin, fit, budgeted); REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy)); if (proxy) { REPORTER_ASSERT(reporter, proxy->asRenderTargetProxy()); // This forces the proxy to compute and cache its // pre-instantiation size guess. Later, when it is actually // instantiated, it checks that the instantiated size is <= to // the pre-computation. If the proxy never computed its // pre-instantiation size then the check is skipped. proxy->gpuMemorySize(); check_surface(reporter, proxy.get(), origin, widthHeight, widthHeight, config, budgeted); int supportedSamples = caps.getRenderTargetSampleCount(numSamples, config); check_rendertarget(reporter, caps, resourceProvider, proxy->asRenderTargetProxy(), supportedSamples, fit, caps.maxWindowRectangles()); } } desc.fFlags = kNone_GrSurfaceFlags; { sk_sp<GrTexture> tex; if (SkBackingFit::kApprox == fit) { tex = resourceProvider->createApproxTexture( desc, GrResourceProvider::Flags::kNoPendingIO); } else { tex = resourceProvider->createTexture( desc, budgeted, GrResourceProvider::Flags::kNoPendingIO); } sk_sp<GrTextureProxy> proxy( proxyProvider->createProxy(format, desc, origin, fit, budgeted)); REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy)); if (proxy) { // This forces the proxy to compute and cache its // pre-instantiation size guess. Later, when it is actually // instantiated, it checks that the instantiated size is <= to // the pre-computation. If the proxy never computed its // pre-instantiation size then the check is skipped. proxy->gpuMemorySize(); check_surface(reporter, proxy.get(), origin, widthHeight, widthHeight, config, budgeted); check_texture(reporter, resourceProvider, proxy->asTextureProxy(), fit); } } attempt++; } } } } } } }