精华内容
下载资源
问答
  • RAC DRM

    2018-08-16 22:14:34
    这边RAC库的入网检查有这么一项:关闭RAC的DRM功能,查看DRM相关参数输出为0。 select a.ksppinm, b.ksppstvl --查看是否关闭DRM功能,如果没有关闭则需要关闭。  from sys.x$ksppi a, sys.x$ksppcv b  where a....

    这边RAC库的入网检查有这么一项:关闭RAC的DRM功能,查看DRM相关参数输出为0。

    select a.ksppinm, b.ksppstvl  --查看是否关闭DRM功能,如果没有关闭则需要关闭。
      from sys.x$ksppi a, sys.x$ksppcv b
     where a.indx = b.indx
       and a.ksppinm in ('_gc_policy_time');结果为0

    alter system set "_gc_policy_time"=0 scope=spfile; --关闭DRM

     

    下面是RAC的DRM的功能,以及为什么要关闭这个功能。

     

    资源主节点

    由于资源可能出现在多个节点里面,一个数据库里面有多个节点,资源可能在每一个节点都出现,但是不能将资源相关的使用信息和锁的信息在每一个节点都存放,这样会导致资源的浪费并且还不能保持一致性。一般资源的信息只存放在一个节点之上,对于某一个具体的资源存放它的使用信息,锁信息,状态信息的这个节点称为资源主节点。保存资源的定义及相关的锁信息的节点。

     

    ORACLE RAC DYNAMIC REMASTERING 

    DRM的引⼊
    在传统的资源访问过程中,资源主节点在第⼀次确认后不再改变,在正常的情况下,对于N个节点的RAC数据库,只有1/N的资源可以在本地节点访问, n-1/n的资源需要到远程节点访问;如果最初确定的资源主节点对于资源访问远⼩于其他节点,更会加重节点间的交互。给性能带来严重的影响。这样就 引入了DRM来解决这个问题。

    DRM定义 

    PCM资源的主节点,能够根据资源在各个节点的访问情况动态地调整。

     

     

    DRM相关参数 

    1. gc_policy_time:指定了Oracle搜集每个节点对某个数据库对象的访问次数的时间间隔。
    2.  gc_policy_minimum:指定了每分钟数据库对象⾄少要被访问多少次,才能考虑修改它的主节点信息。
    3. gc_affinity_ratio:只有当⼀个节点访问某⼀个数据库对象的次数超过了其他所有节点访问相同的数据库对象的多少倍时,才考虑修改对象的主节点。

     

    DRM的实现过程
    主节点迁移过程
    1、静默阶段: LMON进程通知LMS进程不再接受对相关资源的新的操作请求
    2、冻结阶段:对所有要进⾏DRM的数据块进⾏冻结
    3、清除阶段:清除旧的主节点信息
    4、重建阶段:所有实例将对应数据块的锁信息发送⾄新的资源主节点,注意不是拷贝数据块到新节点。
    5、解冻阶段:完成交接后,结束过程

     

    READ MOSTLY - DRM 的延伸(11G版本推出了优秀新特性,例如:read mostly,这个新特性使得内存融合技术在以读为主要操作的数据库对象时变为更加高效)

    背景:
    对于⼀些查询操作占主要的数据块,在正常的RAC访问机制下,需要不断访问资源主节点,消耗不
    必要的资源。
    实现⽅式

    LCK0对数据块的访问⽅式进⾏记录,如果发现某些数据库对象在某⼀段时间内被访问的操作都是读操作,在锁的信息上体现为S的PCM锁,并且访问这些数据库对象经常发⽣实例间通信的话,那么会给这些数据库对象加上read mostly的标志,并且预先对每⼀个节点都赋予对这些数据库对象的读权限。

    适⽤场景
    1、数据库对象绝⼤部分操作都是读,极少进⾏修改操作; 

    2、如果访问该数据库对象,出现⼤量的gc cr grant 2 way和gc current block 2-way和gc current block 3-way等待事件时,那么这个数据库对象适⽤read mostly

    DRM对性能的影响
    DRM的影响
    在DRM的冻结过程中,对应资源的访问请求会被挂起,很可能出现异常,触发bug修改数据IO过⼤;
    Read mostly 影响

    修改数据IO过⼤;
    过渡时期;

     

     

     _gc_policy_time - RAC集群中的DRM管理

     

    DRM是 Dynamic Resource Management 的简称,意思就是动态资源管理。在Oracle RAC中,所有的数据块(Data block)都有一个实例作为主实例进行管理,叫做Master,Master 负责照看好自己所管辖的data block的状态,包括锁定等,并对跨实例访问进行授权。

     

    如果能随着数据块的访问频繁动态的修改数据块的master节点,那么对应GC的grant message则会大量的减少。基于以上考虑,DRM特性应运而生。但是早期的DRM在进行 re-master的过程中长长带来短时的性能影响,在很多重要环境中,这是不能忍受的。

     

    如果希望关闭DRM这个特性,可以结合设置 _gc_policy_time 和  _gc_undo_affinity :

    alter system set "_gc_policy_time" = 0 scope=spfile;

    alter system set "_gc_undo_affinity" = false scope=spfile;

     

     

    下面是别人博客对DRM解释:

    接下来,我们对RAC 环境中,访问一个buffer的过程进行简单的描述。我们以一个4节点的RAC 数据库为例。注意,我们只会列出比较典型的一种情况,不会把所有可能的情况都一一列出,而且只是把步骤进行了简单的介绍。

     

    步骤1:实例3需要以X(exclusive)方式访问buffer1, 向master实例(1) 发出了请求。

    步骤2:master实例(1)发现实例2 以X方式持有buffer1,之后通知实例2释放X lock,并把buffer1发送给实例3。

    步骤3: 实例2释放X lock,并把最新版本的buffer1发送给实例3。

    步骤4:实例3获得buffer1, 并通知master 实例(1)更新资源buffer1的最新状态。

    这里可以看到实例1是master对信息处理的过程:(1)接受requestor请求请求,(2)通知持有该BUFFER1的节点释放资源,(3)接受实例三获得资源最新状态,这里有信息的传递,试想一下如果实例3即requestor如果也是master,那么就节省了向实例1信息传递,这样可以提高性能。

     

    从上面的步骤,我们不难看出,在RAC 数据库中,当我们访问一个buffer的时候,最多会有3个实例参与其中,master实例,holder(持有者)实例 和requestor(申请者) 实例。2种数据传输会出现,message:用于和lock相关的信息传输,data:用于传输buffer。同时,根据上面的步骤我们也自然会想到,如果master和requestor在同一个实例上,那么就可以减少实例之间message的传输并且访问的代码路径(code path)会更短,从而提高性能,但是每个buffer在被读取到buffer cache时,master节点的选择是随机的。基于这种考虑, oracle从10g开始,推出了一个新特性DRM(Dynamic Resource management)。

     


    DRM的主要功能是,根据一段时间内(默认10分钟),每个实例,对某一个数据库对象的 (10gR1以数据文件为单位)的访问次数和方式,来决定数据库对象对应的buffer应该被mastering 到哪一个实例。在指定时间内,如果某一个实例访问某个数据库对象次数高于其他实例一定倍数(默认50倍),则oracle 会把这个对象所有的buffer的master信息,转移到对应实例(注意:不是转移buffer)。当然,转移的过程是渐进式的。当oracle 决定将一个buffer的master实例确定到本地实例后,会对这个buffer上加上affinity lock,来实现快速的访问。这也是我们经常提到的object affinity 的由来。

     

    展开全文
  • DRM Wayland基本概念

    2021-03-03 18:11:42
    1.linux系统中查看屏幕分辨率(通常是在设备树中进行配置的) #2代设备,实际物理尺寸-1.9英寸 $cat /sys/class/graphics/fb0/virtual_size 170,320 #3代设备,实际物理尺寸-2.97英寸 $cat /sys/class/graphics/fb0/...

    1.linux系统中查看屏幕分辨率(通常是在设备树中进行配置的)

    #2代设备,实际物理尺寸-1.9英寸
    $cat /sys/class/graphics/fb0/virtual_size
    
    170,320
    #3代设备,实际物理尺寸-2.97英寸
    $cat /sys/class/graphics/fb0/virtual_size
    480,800
    

    2.lcd外设选型参数

    (1)物理尺寸
    (2)硬件接口
    外部接口种类:hdmi、vga,主要用于连接外部显示器
    内部接口种类:mipi、LVDS、edp,主要用于连接移动端连接显示使用
    
    mipi接口的lcd显示器(在配置dts文件时需要配置2部分内容:mipi接口相关内容和显示屏相关内容):
    mipi引脚
    lcd使能引脚(LCD_EN)
    lcd复位引脚(LCD_RST)
    背光使能引脚(BL_EN)
    
    #用以下命令可以查看注册的gpio引脚(通常这些引脚是在dts文件中进行配置)
    $cat sys/kernel/debug/gpio
    GPIOs 96-127, platform/pinctrl, gpio3:
    gpio-116 (                    |reset               ) out lo
    
    mipi接口:
    目的是把手机内部的接口如摄像头、显示屏接口、射频/基带接口等标准化,从而减少手机涉及的复杂程度,目前比较成熟的接口应用又DSI(显示接口)和CSI(摄像头接口)
    
    lvds接口、mipi接口、edp接口区别
    LVDS接口只用于传输视频数据,MIPI DSI(用于连接lcd,MIPI CSI用于连接摄像头,其中摄像头的接口还有DVP接口即cif接口)不仅能够传输视频数据,还能传输控制指令
    
    (3)分辨率
    (4)数据格式
    lcd支持多种显示格式:例如32bit(4字节)、24bit(3字节)、16bit(2字节)等
    
    #查看一个像素占据的的大小	
    $cat /sys/class/graphics/fb0/bits_per_pixel
    

    3.查看lcd显示屏驱动是否加载成功,出现以下信息表示驱动加载成功

    #在调试阶段主要设置lcd的各个时序参数、时钟、mipi时钟等等
    $demsg
    [    0.893064] rockchip-drm display-subsystem: devfreq is not set
    [    0.894892] rockchip-drm display-subsystem: bound ff460000.vop (ops 0xffffff8008871ec8)
    [    0.896117] rockchip-drm display-subsystem: bound ff140000.syscon:rgb (ops 0xffffff8008869fb8)
    

    4.整个框架流程

    Linux内核DRM框架
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    基本概念如下:
    1.Wayland:显示服务器,是一种协议
    2.Weston:是Wayland协议的的实现
    3.drm又包括:
    drm framebuffer:
    	它是一块内存区域,我把它理解为一块画布,驱动和应用层都能访问它
    plane:
    	图层
    crtc:
    	读取当前扫描缓冲区的像素数据,生成视频模式定时信号.它对内连接 Framebuffer 地址,对外连接 Encoder。它会扫描你画布(Framebuffer)上的内容,叠加上 Planes 的内容,传给 Encoder。
    encoder:
    	将内存的 pixel 像素 编码(转换)为显示器所需要的信号,比如 DVID、VGA、YPbPr、CVBS、Mipi、eDP 等
    connector:
    	直译为 连接器。Connector 常常对应于物理连接器 (VGA, DVI, FPD-Link, HDMI, DisplayPort, S-Video …) 他会连接将一个物理显示输出设备 (monitor, laptop panel, …)
    	
    基本流程:
    app将画好的surface,通过wayland协议提供给compositor,compositor将来自各个应用的surface合成一帧,通过drm接口最终画在Framebuffer上。
    #运行的compositor
    weston --tty=2 -B=drm-backend.so --idle-time=0&
    

    5.测试显示屏

    $modetest -M rockchip
    Encoders:
    id      crtc    type    possible crtcs  possible clones
    65      0       DPI     0x00000001      0x00000000
    
    Connectors:
    id      encoder status          name            size (mm)       modes   encoders
    66      0       connected       DPI-1           23x43           1       65
      modes:
            name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
      170x320 1486 170 175 185 195 320 325 335 345 100000 flags: nhsync, nvsync; type: preferred
    
    CRTCs:
    id      fb      pos     size
    60      0       (0,0)   (0x0)
    
    Planes:
    id      crtc    fb      CRTC x,y        x,y     gamma size      possible crtcs
    58      60      0       0,0             0,0     0               0x00000001
      formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
    
    $modetest -M rockchip -s 66@60:170x320
    
    -M :用于指定访问rockchip drm driver
    -s :<connector_id>@<crtc_id>:<mode>
    

    6.参考文档

    MIPI介绍(CSI DSI接口)
    Mipi 接口 和 LVDS 接口区别
    LVDS,MIPI,EDP
    LCD支持的数据格式
    Rockchip之RK3288解决MIPI屏花屏
    从modetest 到 DRM driver
    Linux 图形栈一览:基于 DRM 和 Wayland
    Linux DRM(二)基本概念和特性

    展开全文
  • 函数原型请查看:xf86drm.c 函数原型请查看:xf86drmMode.c 相关函数 int drmGetCap (int fd, uint64_t capability,uint64_t * value ) 说明:   获取DRM驱动程序的功能。 参数:   [in] fd:打开的DRM设备的文件...

    相关函数英文版请查看:nvidia-Direct Rending Manager
    函数原型请查看:xf86drm.c
    函数原型请查看:xf86drmMode.c

    文章目录

    相关函数

    int drmGetCap (int fd, uint64_t capability,uint64_t * value )

    说明
      获取DRM驱动程序的功能。
    参数
      [in] fd:打开的DRM设备的文件描述符
      [in] capability:需要从设备获取的DRM能力。支持功能:
        DRM_CAP_ASYNC_PAGE_FLIP:如果不支持,value设置为0,如果支持,value设置为1。
        DRM_CAP_DUMB_BUFFER:如果不支持,value设置为0,如果支持,value设置为1。
        DRM_CAP_CURSOR_WIDTH:如果支持该能力,“value”中存储DRM-NVDC允许的最大游标宽度,如果不支持,则为0。
        DRM_CAP_CURSOR_HEIGHT:如果支持该能力,“value”中存储DRM-NVDC允许的最大游标高度,如果不支持,则为0。
        DRM_CAP_TIMESTAMP_MONOTONIC:如果不支持,value设置为0,如果支持,value设置为1。仅支持Linux。
      [out] value:返回capability指定的capability值。
    返回值
      如果成功则为0,否则为-EINVAL。
    函数原型

    /---------------------------drm.h-----------------------------------/
    /** DRM_IOCTL_GET_CAP ioctl argument type */
    struct drm_get_cap {
    	__u64 capability;
    	__u64 value;
    };
    /---------------------------xf86drm.c-----------------------------------/
    drm_public int drmGetCap(int fd, uint64_t capability, uint64_t *value)
    {
        struct drm_get_cap cap;
        int ret;
    
        memclear(cap);
        cap.capability = capability;
    
        ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
        if (ret)
            return ret;
    
        *value = cap.value;
        return 0;
    }
    

    —————————————————————————————————————————

    drmModeResPtr drmModeGetResources (int fd )

    说明
      获取有关DRM设备的crtc、编码器和连接器的信息。
      获取DRM设备的主要资源的列表。DRM应用程序通常在早期调用此函数来识别可用的显示和其他资源。但是,该函数不报告平面资源。这些可以通过drmModeGetPlaneResources查询。
    参数
      fd:打开的DRM设备的文件描述符。
    返回值
      如果成功,则为drmModeResPtr结构,否则为空。
    注意
      drmModeResPtr结构的min_width、min_height、max_width和max_height成员被设置为占位符值。
       drmModeResPtr其实就是_drmModeRes *,结构体下面有。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeFreeResources释放资源信息结构。
    —————————————————————————————————————————

    void drmModeFreeResources(drmModeResPtr ptr)

    说明
      释放资源信息结构。
      释放由drmModeGetResources分配的drmModeResPtr结构。
    参数
      ptr:一个指向待释放资源的指针。

    —————————————————————————————————————————

    drmModeConnectorPtr drmModeGetConnector(int fd,uint32_t connector_id )

    说明
      获取连接器的信息。
      如果connector_id是有效的,获取一个drmModeConnectorPtr结构,该结构包含连接器的信息,例如可用模式、连接状态、连接器类型和附加的编码器(如果有的话)。
    参数
      fd:打开的DRM设备的文件描述符。
      connector_id:要检索的连接器的连接器ID。
    返回值
      如果成功,则为drmModeConnectorPtr结构;如果找不到连接器或API内存不足,则为NULL。
    注意
      连接器->mmWidth和连接器->mmHeight目前设置为占位符值。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeFreeConnector释放连接器信息结构。

    —————————————————————————————————————————

    void drmModeFreeConnector(drmModeConnectorPtr ptr )

    说明
      释放一个连接器。
      释放drmModeGetConnector分配的drmModeConnectorPtr结构。
    参数
      ptr:一个指向待释放资源的指针。

    —————————————————————————————————————————

    drmModeEncoderPtr drmModeGetEncoder (int fd,uint32_t encoder_id )

    说明
      获取编码器的信息。
      获取一个drmModeEncoderPtr结构,它包含关于指定编码器的信息,例如当前的CRTC和兼容的CRTC。
    参数
      fd:打开的DRM设备的文件描述符。
      crtc_id:要检索的CRTC的CRTC ID。
    返回值
      如果成功,则为drmModeEncoderPtr结构;如果找不到编码器或API内存不足,则为NULL。
    注意
      DRM-NVDC中的编码器在启动时连接到单个CRTC,并且不能重新配置。在possible_crtcs中只设置了一个位,而在possible_cloning中没有设置位(也就是说,possible_cloning的值为0)。
    后置条件
      如果调用成功,应用程序必须调用drmModeFreeEncoder来释放分配的结构。

    —————————————————————————————————————————

    void drmModeFreeEncoder(drmModeEncoderPtr ptr)

    说明
      释放一个编码器。
      释放drmModeEncoderPtr由drmModeGetEncoder分配的结构。
    参数
      ptr:一个指向待释放资源的指针。
    —————————————————————————————————————————

    int drmIoctl(int fd, unsigned long request, void * arg )

    说明
      发出DRM输入/输出控制(IOCTL)。
      这个函数主要用于LIBDRM不支持执行所需操作的函数的情况。LIBDRM在特性上可能落后于内核接口,这个函数允许尽早访问新接口。
    参数
      [in] fd:打开的DRM设备的文件描述符。
      [in] reques:一个支持的DRM IOCTL…常量。
      [in,out] arg:指向ioctl数据结构的指针:
        如果请求是DRM_IOCTL_MODE_CREATE_DUMB,一个drm_mode_create_dumb结构
        如果请求是DRM_IOCTL_MODE_MAP_DUMB, drm_mode_map_dumb结构
        如果请求是DRM_IOCTL_MODE_DESTROY_DUMB,一个drm_mode_destroy_dumb结构
    返回值
      如果成功,则为0,否则为-1。
    注意
      DRM- nvdc不支持内核DRM的所有功能,所以只实现了一小部分IOCTL操作。
    DRM-NVDC支持以下应用程序使用的IOCTL操作:
        DRM_IOCTL_MODE_CREATE_DUMB:创建一个哑(CPU)缓冲区。用于调试和简单的显示测试。加速渲染不可用。
        DRM_IOCTL_MODE_MAP_DUMB::映射一个用于CPU访问的哑缓冲区。与内核DRM不同,DRM- nvdc用mmap函数映射dumb缓冲区,并在返回的偏移量中返回一个有效的内存指针。应用程序不能在返回的偏移量上调用mmap。
        DRM_IOCTL_MODE_DESTROY_DUMB:销毁一个哑缓冲区。
        DRM_IOCTL_TEGRA_GEM_CREATE:创建一个HW缓冲区。

    —————————————————————————————————————————

    int drmModeAddFB (int fd, uint32_t width, uint32_t height, uint8_t depth, uint8_t bpp, uint32_t pitch, uint32_t bo_handle, uint32_t * buf_id )

    说明:
      创建一个framebuffer.。
      该函数使用指定的缓冲区对象作为内存后备存储,以指定的大小和格式创建一个framebufferbuffer对象可以是通过调用drmIoctl创建的“哑缓冲区”,请求参数设置为DRM_IOCTL_MODE_CREATE_DUMB,也可以是通过调用drmPrimeFDToHandle函数导入的dma-buf
    参数:
      [in] fd:打开的DRM设备的文件描述符。
      [in] width:framebuffer的宽度以像素为单位。
      [in] height:framebuffer高度(像素)。
      [in] depth:framebuffer.深度,以比特为单位。
      [in] bpp:framebuffer.每像素位。
      [in] pitch:framebuffer间距,以字节为单位。
      [in] bo_handle:提供内存支持的缓冲区对象的句柄。
      [out] buf_id:在创建成功时接收到创建的framebuffer的ID。
    返回值:
      如果framebuffer创建成功,则为0,否则为-1。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeRmFB来删除(释放)framebuffer。
    —————————————————————————————————————————

    int drmModeRmFB(int fd, uint32_t fb_id )

    说明
      破坏一个framebuffer.。
      销毁(释放)由drmModeAddFB或drmModeAddFB2分配的帧缓冲区。
    参数
       fd:打开的DRM设备的文件描述符。
       fb_id:要销毁的framebuffer的ID。

    返回值
      如果销毁成功则为0,如果没有找到framebuffer则为-ENOENT。
    —————————————————————————————————————————

    drmModeCrtcPtr drmModeGetCrtc(int fd,uint32_t crtc_id)

    说明:
      获取CRTC的信息。
      如果指定的CRTC ID有效,则获取一个drmModeCrtcPtr结构,该结构包含关于CRTC的信息,例如当前framebuffer、模式、位置、大小和gamma LUT元素的数量。
    参数:
       fd:打开的DRM设备的文件描述符。
       crtc_id:要检索的CRTC的CRTC ID。
    返回值:
      如果成功,则为drmModeCrtcPtr结构;如果找不到CRTC或API内存不足,则为NULL。
    后置条件
      如果调用成功,应用程序必须调用drmModeFreeCrtc来释放它返回的结构。
    —————————————————————————————————————————

    int drmModeSetCrtc (int fd,uint32_t crtc_id,uint32_t fb_id,uint32_t x,uint32_t y,uint32_t * connectors,int count,drmModeModeInfoPtr drm_mode )

    说明:
      设置CRTC配置。
      如果指定了DRM模式(如果drm_mode不为NULL),在CRTC和指定的连接器上设置显示模式。新的fb_id, x,和y属性将设置在vblank。
    参数:
      fd:打开的DRM设备的文件描述符。
      crtc_id:要设置的CRTC的ID。
      fb_id:此CRTC显示的帧缓冲区id,或者-1使用与前面操作相同的CRTC。
      x:从活动显示区域左侧到放置framebuffer的x偏移量。如果x是-1,x的偏移量不会改变。
      y:从活动显示区域顶部到放置framebuffer的y偏移量。如果y是-1,y的偏移量不会改变。
      connectors:一个指向要绑定到CRTC的连接器列表的指针。
      count:连接器列表中的连接器数量。
      drm_mode:设置模式,或NULL使用与前面操作相同的模式。
    返回值
      0:如果成功
      -EINVAL:如果无效的“crtc id”。
      -1:如果count无效,或者连接器指定的列表与CRTC不兼容。
      -errno:另外
    —————————————————————————————————————————

    void drmModeFreeCrtc ( drmModeCrtcPtr ptr )

    说明
      释放一个CRTC。
      释放由drmModeGetCrtc分配的drmModeCrtcPtr结构。
    参数:
      ptr:一个指向需要释放的CRTC的指针。
    —————————————————————————————————————————

    int drmSetClientCap ( int fd, uint64_t capability, uint64_t value )

    说明:
       启用或禁用DRM特性(功能)。
    参数:
       fd:打开的DRM设备的文件描述符。
       capability:指定要启用或禁用的功能。支持的值是:
         DRM_CLIENT_CAP_ATOMIC (disabled by default)
         DRM_CLIENT_CAP_UNIVERSAL_PLANES (disabled by default)
       value:0表示禁用,1表示启用。
    返回值
       0表示成功,否则为-EINVAL。
    —————————————————————————————————————————

    int drmModeCreatePropertyBlob ( int fd, const void * data, size_t size, uint32_t * id )

    说明:
      创建一个属性斑点( property blob)。
      存储一个不透明的内存块并返回它的ID。然后,可以将ID用于原子模式设置。.
    注意:
      DRM-NVDC中,data必须为drmModeModeInfoPtr。当从drmModeModeInfoPtr创建属性blob时,返回的ID将成为CRTC属性中匹配名称MODE_ID的有效值。原子地将MODE_ID属性提交到创建的blobID会导致在该CRTC上设置模式。新的CRTC模式将是drmModeModeInfoPtr作为输入drmModeCreatePropertyBlob的模式。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeDestroyPropertyBlob销毁(释放)属性blob。
    参数:
       fd:打开的DRM设备的文件描述符。
       data:属性blob的内容。什么数据是可接受的取决于实现。在DRM-NVDC中,数据必须是drmModeModeInfoPtr结构。
       size:data的大小
       id:返回blob的属性ID
    返回值
       0: 如果操作成功。
       -1:如果data不是一个有效的指针,或者如果size或id无效。
       -ENOMEM:如果不能分配块内存。
    —————————————————————————————————————————

    drmModePlanePtr drmModeGetPlane ( int fd, uint32_t plane_id )

    说明:
      获取有关plane的信息。
      :如果plane_id有效,则获取一个drmModePlanePtr结构,该结构包含关于指定平面的信息,例如它当前的CRTC和兼容的CRTC,当前绑定的framebuffer, gamma步数,以及平面的位置。
    注意:
      在DRM-NVDC中,平面在启动时连接到单个CRTC,且不可重构。drmModePlanePtr结构的possible_crtc成员总是恰好设置了一位。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeFreePlane释放平面信息结构。
    参数:
       fd:打开的DRM设备的文件描述符。
       fd::Plane待检索的planeID。
    返回值
       如果成功,则为drmModePlanePtr结构,如果没有找到平面或API内存不足,则为NULL。
    —————————————————————————————————————————

    drmModeObjectPropertiesPtr drmModeObjectGetProperties ( int fd,uint32_t object_id, uint32_t object_type )

    说明:
      获取DRM对象的所有属性。
      获取对象属性结构,该结构描述指定DRM对象的所有原子性可修改属性,以及不包含在相应drmModeCrtcPtrdrmModeConnectorPtrdrmModePlanePtr结构中的只读属性。然后,你可以通过drmModeGetProperty来检索单个属性,并通过drmModeAtomicAddProperty来改变它们的值。
      drmModeObjectPropertiesPtr结构包含一个属性id数组(props)、一个对应属性值数组(prop_values)和每个数组中的元素数(count_props)。您可以通过在属性ID上调用drmModeGetProperty并查看返回的drmModePropertyPtr结构的名称字段来获得属性的名称。
      要以原子方式修改属性,可以通过调用drmModeAtomicAlloc创建一个drmModeAtomicReqPtr请求对象,然后调用drmModeAtomicAddProperty,指定drmModeAtomicReqPtr对象、要修改对象的对象ID、要修改属性的属性ID和属性的新值。然后使用drmModeAtomicCommit提交请求。您可以在原子请求中设置多个属性,并在单个操作中提交它们。
      
    注意:
      并不是所有对象类型都受支持。
    后置条件
      如果调用成功,应用程序必须通过调用drmModeFreeObjectProperties释放drmModeObjectPropertiesPtr结构体。
    参数:
       fd:打开的DRM设备的文件描述符。
       object_id:要检索其属性的DRM对象的对象ID。
       object_type:表示对象类型的符号。支持以下对象类型:
          DRM_MODE_OBJECT_CRTC
          DRM_MODE_OBJECT_CONNECTOR
          DRM_MODE_OBJECT_PLANE
    返回值
       如果成功,则为drmModeObjectPropertiesPtr对象,否则为NULL
    —————————————————————————————————————————

    drmModePropertyPtr drmModeGetProperty ( int fd, uint32_t propertyId )

    说明:
      获取描述DRM对象的属性的属性结构。
      DRM对象可以是一个平面、一个CRTC或一个连接器。
      这个函数操作drmModeObjectPropertiesPtr结构体,该结构体由drmModeObjectGetProperties()返回。
      可修改的属性取决于DRM对象类型:
        ①对于一个平面(对象类型DRM_MODE_OBJECT_PLANE):
            "SRC_X", "SRC_Y", "SRC_W", "SRC_H", "zpos", "alpha" "CRTC_X",
            "CRTC_Y", "CRTC_W", "CRTC_H", "CRTC_ID", "FB_ID"
        ②对于一个CRTC(对象类型DRM_MODE_OBJECT_CRTC),支持的值是:
            "MODE_ID", "ACTIVE", "HDR_SUPPORTED"
        ③对于连接器(对象类型DRM_MODE_OBJECT_CONNECTOR),支持的值是:
            "CRTC_ID"
    对于DRM平面,enum字段保存了定义属性的关键字对(名称:值)列表。

    drmModePropertyPtr->enums[ ].
    namedrmModePropertyPtr->enums[ ].value
    

        名称字段支持的值在上面定义(例如,“SRC_X”,“SRC_Y”,或“SRC_W”)。该字段是可修改的。
        value字段支持的值为:
          "Primary", "Overlay", "Cursor"
        该字段是只读的.
        要识别平面类型,请遍历下面的列表来定位值字段与您要查找的值字段匹配的枚举。然后,从对应的名称字段获取值。
          drmModePropertyPtr->enums[ ]
    注意:
      一个平面的zpos值初始化为相对于下一个平面的偏移量10。这是为了允许头部的灵活配置。例如:“Primary”类
        •"Primary" type Plane zpos = 10
        •First "Overlay" Plane zpos = 20
        •Next "Overlay" Plane zpos = 30
        •Etc.
      zpos的允许范围是[0,255]。数值上较大的平面遮挡数值上较小的平面。一个平面的alpha值将导致一个平面范围的透明度以及包含在缓冲区对象中的像素alpha被应用。alpha的允许范围是[0,255],其中0是完全透明的
    后置条件
      如果调用成功,应用程序必须通过调用drmModeFreeProperty释放属性信息结构。
    参数:
       fd:打开的DRM设备的文件描述符
       propertyId:要获取的属性对象的属性ID。
    返回值
       如果成功,则为drmModePropertyPtr,否则为NULL。
    —————————————————————————————————————————

    int drmModeAtomicAddProperty ( drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value )

    说明:
      向原子请求添加属性。
      向原子请求添加属性和值。
    参数:
       req:一个原子请求。
       object_id:需要修改的CRTC、平面或连接器的对象ID。
       property_id:属性需要修改的属性ID。
       value:属性的新值。
    返回值
       0:如果成功
       -1:如果req是NULL或者API内存不足。
       -EINVAL:如果DRM_CLIENT_CAP_ATOMIC未启用。
    —————————————————————————————————————————

    drmModePlaneResPtr drmModeGetPlaneResources ( int fd )

    说明:
      获取Plane的有关信息。
      获取DRM设备的平面资源列表。DRM应用程序通常会提前调用这个函数来识别可用的显示层。
      默认情况下,返回的信息只包括“叠加”类型(常规)平面,而不是“主”和“光标”平面。如果DRM_CLIENT_CAP_UNIVERSAL_PLANES已被drmSetClientCap启用,则返回的信息包括“Primary”平面表示CTRCs,“Cursor”平面表示Cursors。这允许使用平面函数(如drmModeSetPlane)来操作crtc和游标。

    注意
      DRM-NVDC目前不实现“游标”类型平面。
    后置条件
      打开DRM设备的文件描述符。
    参数
       fd:打开的DRM设备的文件描述符。
    返回值
       如果成功,则为drmModeResPtr结构,否则为NULL
    —————————————————————————————————————————

    int drmHandleEvent ( int fd, drmEventContextPtr evctx )

    说明:
      轮询事件,指定回调函数。
      如果发生了指定类型的事件,则调用回调函数。
    注意:
      DRM-NVDC仅支持Linux操作系统。支持evctx结构的vblank_handler字段。
    后置条件
      
    参数:
       fd:打开的DRM设备的文件描述符。
       evctx:包含回调指针的事件上下文
    返回值
       如果成功则为0,否则为-1。
    —————————————————————————————————————————

    int drmModePageFlip ( int fd, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, void * user_data )

    说明:
      请求指定CRTC上的页面翻转(framebuffer更改)。
      在指定的CRTC上安排翻页。默认情况下,CRTC将被重新编程,以在下一次垂直刷新后显示指定的framebuffer。
    注意:
      drmModePageFlip不会等待呈现完成,也不会在翻转完成之前阻止未来的呈现。这与利用隐式同步的基于KMS的实现不同。当使用EGLOutput和DRM-NVDC时,同步是在内部处理的。
    参数:
       fd:打开的DRM设备的文件描述符。
       crtc_id:CRTC要修改framebuffer的CRTC ID。
       fb_id:Framebuffer要显示的Framebuffer ID。
       flags:影响操作的标志。支持的值是:
            DRM_MODE_PAGE_FLIP_ASYNC:立即翻转,而不是vblank
            DRM_MODE_PAGE_FLIP_EVENT:发送翻页事件。
       user_data:如果请求vblank事件,则页面翻转处理程序使用的数据。
    返回值
       0 if successful.
      -EINVAL if crtc_id or fb_id is invalid.
      -errno otherwise
    —————————————————————————————————————————

    int drmModeSetPlane ( int fd, uint32_t plane_id, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, uint32_t crtc_x, uint32_t crtc_y, uint32_t crtc_w, uint32_t crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h )

    说明:
      更改平面的framebuffer和位置
    注意:
      crtc_……和src_……参数接受特殊的输入值-1,这表示不改变硬件偏移值。(当给定这个值时,基于内核的DRM驱动程序返回错误代码-ERANGE。)平面上设置的framebuffer显示在crtc的顶部。平面的堆叠顺序由drmModeGetPlaneResources报告平面的顺序表示。所有drmModeSetPlane操作都同步到vblank并阻塞。
    参数:
       fd::打开的DRM设备的文件描述符。
       plane_id:平面需要修改的平面ID。
       crtc_id:CRTC该平面所在CRTC的ID
       fb_id:Framebuffer在平面上显示的Framebuffer ID,或-1表示保持Framebuffer不变。
       flags:控制函数行为的标志。目前不支持外部使用标志。
       crtc_x:从有源显示区域左侧显示平面的偏移量
       crtc_y:从有源显示区域顶部到显示平面的偏移量。
       crtc_w:显示输出矩形的宽度。
       crtc_h:显示输出矩形的高度
       src_x:从源framebuffer左侧的剪辑偏移量(Q16.16固定点)。
       src_y:来自源framebuffer顶部的剪辑偏移量(Q16.16固定点)。
       src_w:源矩形的宽度(Q16.16固定点)。
       src_h:源矩形的高度(Q16.16固定点)。

    返回值
       0 : 如果成功
       -EINVAL:plane_id或crtc_id无效
       -errno:otherwise
    —————————————————————————————————————————

    drm

    说明:
      
      
    注意:
      
    后置条件
      
    参数:
       fd:
       fd:
    返回值
      

    —————————————————————————————————————————

    相关结构体

    设备:dev、drmModeModeInfo

    struct modeset_dev {
    	struct modeset_dev *next;		/指向下一个设备指针
    	uint32_t width;					/缓冲区对象的宽度
    	uint32_t height;				/缓冲区对象的高度
    	uint32_t stride;				/缓冲区对象的步幅
    	uint32_t size;					/缓冲区对象的大小
    	uint32_t handle;				/
    	uint8_t *map;					/指向内存映射缓冲区的指针
    	drmModeModeInfo mode;			/显示模式
    	uint32_t fb;					/
    	uint32_t conn;					/连接器ID
    	uint32_t crtc;					/crtc ID
    	drmModeCrtc *saved_crtc;		/更改crtc前的配置
    };
    
    typedef struct _drmModeModeInfo {
    	uint32_t clock;
    	uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
    	uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;
    
    	uint32_t vrefresh;
    
    	uint32_t flags;
    	uint32_t type;
    	char name[DRM_DISPLAY_MODE_LEN];
    } drmModeModeInfo, *drmModeModeInfoPtr;
    

    资源:drmModeRes

    typedef struct _drmModeRes {
    
    	int count_fbs;					/
    	uint32_t *fbs;					
    
    	int count_crtcs;				/显示控制器总数
    	uint32_t *crtcs;
    
    	int count_connectors;			/连接器总数
    	uint32_t *connectors;
    
    	int count_encoders;				/编码器总数
    	uint32_t *encoders;
    
    	uint32_t min_width, max_width;
    	uint32_t min_height, max_height;
    } drmModeRes, *drmModeResPtr;
    

    连接器:drmModeConnector

    typedef struct _drmModeConnector {
    	uint32_t connector_id;					/当前连接到的连接器ID
    	uint32_t encoder_id; 					/当前连接到的编码器ID
    	uint32_t connector_type;				/当前连接到的连接器类型
    	uint32_t connector_type_id;				/当前连接到的连接器类型ID
    	drmModeConnection connection;			/当前连接器的连接状态(可看下面enum)
    	uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
    	drmModeSubPixel subpixel;
    
    	int count_modes;						/连接器的模式
    	drmModeModeInfoPtr modes;
    
    	int count_props;
    	uint32_t *props; /**< List of property ids */
    	uint64_t *prop_values; /**< List of property values */
    
    	int count_encoders;
    	uint32_t *encoders; /**< List of encoder ids */
    } drmModeConnector, *drmModeConnectorPtr;
    
    typedef enum {
    	DRM_MODE_CONNECTED         = 1,
    	DRM_MODE_DISCONNECTED      = 2,
    	DRM_MODE_UNKNOWNCONNECTION = 3
    } drmModeConnection;
    

    编码器:drmModeEncoder

    typedef struct _drmModeEncoder {
    	uint32_t encoder_id;
    	uint32_t encoder_type;
    	uint32_t crtc_id;
    	uint32_t possible_crtcs;
    	uint32_t possible_clones;
    } drmModeEncoder, *drmModeEncoderPtr;
    

    CRTC:drmModeCrtc

    typedef struct _drmModeCrtc {
    	uint32_t crtc_id;
    	uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */
    
    	uint32_t x, y; /**< Position on the framebuffer */
    	uint32_t width, height;
    	int mode_valid;
    	drmModeModeInfo mode;
    
    	int gamma_size; /**< Number of gamma stops */
    
    } drmModeCrtc, *drmModeCrtcPtr;
    

    标题

    /---------------drm_mode.h-------------/
    /* create a dumb scanout buffer */
    struct drm_mode_create_dumb {
    	__u32 height;
    	__u32 width;
    	__u32 bpp;
    	__u32 flags;
    	/* handle, pitch, size will be returned */
    	__u32 handle;
    	__u32 pitch;
    	__u64 size;
    };
    struct drm_mode_destroy_dumb {
    	__u32 handle;
    };
    
    /* set up for mmap of a dumb scanout buffer */
    struct drm_mode_map_dumb {
    	/** Handle for the object being mapped. */
    	__u32 handle;
    	__u32 pad;
    	/**
    	 * Fake offset to use for subsequent mmap call
    	 *
    	 * This is a fixed-size type for 32/64 compatibility.
    	 */
    	__u64 offset;
    };
    
    展开全文
  • 通过DRM-X4.0,您可以对网页内容进行加密,包括HTML, css, Java Script 和 图片,并且可以控制允许哪些用户查看您的网页内容,禁止复制,禁止打印和截屏,当在过期时不允许查看网页内容。 它使用海海软件强大并私有...

    DRM-X 4.0 HTML网页加密教程 DRM-X 4.0 HTML网页加密教程
    通过DRM-X4.0,您可以对网页内容进行加密,包括HTML, css, Java Script 和 图片,并且可以控制允许哪些用户查看您的网页内容,禁止复制,禁止打印和截屏,当在过期时不允许查看网页内容。

    它使用海海软件强大并私有的加密方法和DRM-X 4.0数字版权管理平台对网页内容进行加密,以防止未经授权对网页内容进行访问。

    网页内容加密步骤:
    第一步、下载安装Xvast浏览器

    首先我们需要下载安装Xvast浏览器,通过浏览器访问www.xvast.cn下载Windows版Xvast,下载后完成安装。

    第二步、操作DRM-X 4.0管理后台

    1. 运行Xvast浏览器后,访问4.drm-x.cn,登录您的帐号
    2. 下载并安装Xvast加密客户端程序
    3. 进入许可证权限页面,创建许可证权限。

    依次填写权限信息,在"保护文档设置"中启用保护文档。在"动态水印"设置中启用水印,将用户名设置为水印的显示文字,我们需要勾选"用户名"选项,设置水印的显示位置和字体大小。第二种类型的水印是以跑马灯的形式显示的,仅在视频中可用,如果要开启,请在这里选择水印的颜色。选择黑名单程序。保存设置。

    1. 进入许可证模版页面,创建许可证模版。

    输入许可证模版的名称,选择刚才创建的许可证权限。

    1. 加密网页文件

    首先需要准备好需要加密的网页内容文件,进入到"加密文件"页面,第一步选择许可证模版,选择后会自动显示这个模版下的许可证权限和关联的用户组,编辑后点击"应用"按钮保存设置。点击第四步的"弹出加密窗口"按钮弹出加密窗口。

    在加密程序中,首先需要为加密文件设置输出路径,选择"添加新输出文件夹",新建一个文件夹放置加密后的网页内容。需要去掉"为加密文件添加_P后缀"的选项,(因为如果加密的内容中有视频文件,这个视频在网页中有调用的话,网页将无法找到这个视频文件,所以我们需要去掉这个选项。)

    接下来需要浏览要加密的文件,我们这里直接"浏览文件夹…"

    点击开始按钮,开始加密。加密最后,如果文件夹中有不支持加密的文件,程序会提示您是否复制这些文件到输出文件夹,我们建议选择"复制"。

    第三步、使用Xvast浏览加密后的网页

    1. 在加密后的网页上右键,选择"使用Xvast打开",浏览器会自动跳转到获取许可证页面,需要您登录获取许可证才能访问网页。

    2. 您可以将加密后的网页上传到服务器上,然后在Xvast浏览器地址栏中输入服务器上的网页URL进行访问。

    那么,如果用户使用其他的浏览器访问加密后的网页会是什么样呢?
    用户使用其他的网页访问加密后的网页将会看到网页显示的乱码,并且在最上面将会提示用户说"请使用Xvast浏览器打开这个内容"
    DRM-X 4.0 加密系统还可以跟您的网站进行集成,集成后,您可以根据自己的模式来控制用户的登录验证和获取许可证。如果您的网站是动态网页,可以批量生成静态网页后再对网页内容进行加密。

    展开全文
  • RAC禁用DRM特性

    2017-11-15 14:21:00
    查看“_gc”开头的隐藏参数值: setlinesize333 colnamefora35 coldescriptionfora66 colvaluefora30 SELECTi.ksppinmname, i.ksppdescdescription, CV.ksppstvlVALUE FROMs...
  • 在本周的工作中为解决客户问题,查看awtk-linux-fb中的源码,其中对于里面关于DRM的内容很感兴趣,请教同事后又上网查了资料,本文对DRM的学习做了总结记录,并以C语言练习了DRM的使用。在此感谢回答我疑问的同事。 ...
  • DRM有三种类型:-Forward-lock(FL):这种DRM是不能被发送或转发的,但它是没有权限设定的,用户可以任意的查看或播放。-Combined delivery(CD):这种DRM是不能被发送或转发的,它的权限和内容是绑定在一起的-S
  • 昨天在网上冲浪,突然一个网站的页面阻挡了我,我没法查看网页内容,由于正好最近在做一个网站,所以她强烈的吸引了我!!!!我打开源码看,一看有个 哦!!!原来有加密的文件,我上网查”bk_htmlview.dll”,相知道这是一个...
  • 这边主要参考以下博客,前辈们水平很高,写的很详细,详细的知识学习可查看以下链接。 详细请看:   何小龙CSDN:https://blog.csdn.net/hexiaolong2009/article/details/83720940   源码获取地址:hexiaolong...
  • 对于第三方应用如Google music等应用无法播放DRM音乐的问题。这里面我们重点记录一下MTK项目上的处理方法。 1.首先我们需要知道我们要添加应用的包名。adb shell ;top 查看我们要添加的应用的包名。 31597 u0_...
  • 1、请使用adb shell ps,查看com.google.android.music的process的名称。Play Music应该会有两个process: com.google.android.music:ui ...2、请在mediatek\frameworks\av\drm\mtkwhitelist\DrmMtkDef.cpp中的
  • 这边主要参考以下博客,前辈们水平很高,写的很详细,详细的知识学习可查看以下链接。 详细请看:   David Herrmann’s Blog: Linux DRM Mode-Setting API   David Herrmann’s Github: drm-howto/modeset.c 源...
  • Audfree DRM Audio Converter for Mac是一个完整的音频解决方案,通过将音频从一种格式转换为另一种格式,可以帮助您完全...现在,请按照此处的完整指南查看如何转换Apple Music,iTunes M4P和Audible AA / AAX图书并将
  • Google Chrome 浏览器最近做出了多项并不招人喜欢的改变: 1)隐藏 SSL 证书信息,用户无法从地址栏的HTTPS连接状态获取到相关的证书信息,而在这之前,用户点击 HTTPS 连接的绿色锁图标就能查看...2)禁止禁用 DRM...
  • DRM出现错误的原因  数字版权管理 (DRM) 系统损坏,因为网络的不...第1步:打开“我的电脑”--此窗口菜单条“工具”--文件夹选项--查看--高级设置-取消“隐藏受保护的操作系统文件 ”的选项,同时选择“隐藏文件...
  • 数字版权管理 (DRM)

    千次阅读 2017-06-13 14:09:34
    此文章由人工翻译。 将光标移到文章的句子上,以查看原文。 译文 原文
  • 参考该博文... 一台ubuntu 16.04 机器重装显卡驱动, 查看linux 版本内核 username -a 进入对应内核路径 cd /lib/modules/4.4.0-83-generic/kernel/drivers/gpu/drm/nouveau sudo rm...
  • 若想具体查看相关函数和结构体的样子可看下篇:学习篇5:相关函数与结构体 详细请看:   David Herrmann’s Blog: Linux DRM Mode-Setting API   David Herrmann’s Github: drm-howto/modeset.c 简化代码 #d
  • Linux DRM(六) -- xrandr

    2020-11-19 13:22:04
    1.Linux下查看本机显示器分辨率: uos@uos-PC:~$ xrandr Screen 0: minimum 320 x 200, current 1600 x 1200, maximum 16384 x 16384 HDMI-0 disconnected (normal left inverted right x axis y axis) DVI-0 ...
  • 这边主要参考以下博客,前辈们水平很高,写的很详细,详细的知识学习可查看以下链接。 详细请看:   蜗窝科技:http://www.wowotech.net/graphic_subsystem/graphic_subsystem_overview.html   ...
  • eidolon具有附加功能的steam_suite到rust的转换。 提供一个基于TUI的注册表,用于Linux eidolon上的无drm,葡萄酒和Steam游戏。...实际运行中查看安装现在,您可以从crates.io安装。 只需运行货物安装eidolon并安装rofi
  • 平台 内核版本 安卓版本 RK3399 Linux4.4 Android7.1 文章目录 edp驱动被分成两个文件 ...drm驱动文件 ...首先查看: 目录kernel/drivers/gpu/drm$ vim bridge/analogix/analogix_...
  • 讨论版权的学者经常观察... 通过在一处查看所有这些提案的政治历史,本文显示了版权政治的明确轨迹,从相对容易的行业间谈判时代到版权产业面临永久,有原则的反对的时代。受到了历史上最大规模的在线抗议活动的鼓舞。
  • 在本教程中(使用Azure媒体服务创建和使用HTML5视频的系列教程的第二部分),我将介绍使用视频录制工具摄取内容的方式以及加密或保护视频的方式,以便只有获得许可的查看者才能查看它。
  • 不顾近三成成员反对,W3C(万维网联盟)正式宣布将加密媒体扩展 (EME) —— 即集成 DRM 数字版权保护的 API 纳入 HTML5 建议标准。
 EME 一直以来都备受争议,EME 由 Google、Microsoft 和 Netflix 等公司的...
  • 客户一套运行在Oracle 10.2.0.5 RAC上的系统,间歇性地出现性能问题。其性能现象为前台反映性能缓慢,从系统上看CPU利用率大幅增加,load增加。...如果再查看更细的等待数据,可以发现其他问题: 从上面的数据...
  • 该示例项目是由GroupDocs展示小组创建的,目的是演示使用商业库– GroupDocs.Viewer for .NET构建的ASP.NET PDF查看器的主要优点。 使用查看器,您可以在所有标准网络浏览器(IE8 +,Chrome,Mozilla Firefox,...

空空如也

空空如也

1 2 3 4 5 6
收藏数 104
精华内容 41
关键字:

drm查看