Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Xf86 Video Fbturbo
Commits
4995422b
Commit
4995422b
authored
Jun 17, 2013
by
Siarhei Siamashka
Browse files
HACK: test for DMA optimized fb_copyarea in the Raspberry Pi kernel
parent
06f5aec6
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/Makefile.am
View file @
4995422b
...
...
@@ -36,6 +36,8 @@ sunxifb_drv_la_SOURCES = \
cpuinfo.h
\
cpu_backend.c
\
cpu_backend.h
\
fb_copyarea.c
\
fb_copyarea.h
\
backing_store_tuner.c
\
backing_store_tuner.h
\
interfaces.h
\
...
...
src/fb_copyarea.c
0 → 100644
View file @
4995422b
/*
* Copyright © 2013 Siarhei Siamashka <siarhei.siamashka@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "fb_copyarea.h"
/*
* HACK: non-standard ioctl, which provides access to fb_copyarea accelerated
* function in the kernel. It just accepts the standard fb_copyarea structure
* defined in "linux/fb.h" header
*/
#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea)
fb_copyarea_t
*
fb_copyarea_init
(
const
char
*
device
,
void
*
xserver_fbmem
)
{
fb_copyarea_t
*
ctx
=
calloc
(
sizeof
(
fb_copyarea_t
),
1
);
struct
fb_var_screeninfo
fb_var
;
struct
fb_fix_screeninfo
fb_fix
;
struct
fb_copyarea
copyarea
;
int
tmp
,
version
;
int
gfx_layer_size
;
int
ovl_layer_size
;
/* use /dev/fb0 by default */
if
(
!
device
)
device
=
"/dev/fb0"
;
ctx
->
fd
=
open
(
device
,
O_RDWR
);
if
(
ctx
->
fd
<
0
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
/*
* Check whether the FBIOCOPYAREA ioctl is supported by requesting to do
* a copy of 1x1 rectangle in the top left corner to itself
*/
copyarea
.
sx
=
0
;
copyarea
.
sy
=
0
;
copyarea
.
dx
=
0
;
copyarea
.
dy
=
0
;
copyarea
.
width
=
1
;
copyarea
.
height
=
1
;
if
(
ioctl
(
ctx
->
fd
,
FBIOCOPYAREA
,
&
copyarea
)
!=
0
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
if
(
ioctl
(
ctx
->
fd
,
FBIOGET_VSCREENINFO
,
&
fb_var
)
<
0
||
ioctl
(
ctx
->
fd
,
FBIOGET_FSCREENINFO
,
&
fb_fix
)
<
0
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
if
(
fb_fix
.
line_length
%
4
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
/* store the already existing mapping done by xserver */
ctx
->
xserver_fbmem
=
xserver_fbmem
;
ctx
->
xres
=
fb_var
.
xres
;
ctx
->
yres
=
fb_var
.
yres
;
ctx
->
bits_per_pixel
=
fb_var
.
bits_per_pixel
;
ctx
->
framebuffer_paddr
=
fb_fix
.
smem_start
;
ctx
->
framebuffer_size
=
fb_fix
.
smem_len
;
ctx
->
framebuffer_height
=
ctx
->
framebuffer_size
/
(
ctx
->
xres
*
ctx
->
bits_per_pixel
/
8
);
ctx
->
gfx_layer_size
=
ctx
->
xres
*
ctx
->
yres
*
fb_var
.
bits_per_pixel
/
8
;
ctx
->
framebuffer_stride
=
fb_fix
.
line_length
/
4
;
if
(
ctx
->
framebuffer_size
<
ctx
->
gfx_layer_size
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
if
(
ctx
->
xserver_fbmem
)
{
/* use already existing mapping */
ctx
->
framebuffer_addr
=
ctx
->
xserver_fbmem
;
}
else
{
/* mmap framebuffer memory */
ctx
->
framebuffer_addr
=
(
uint8_t
*
)
mmap
(
0
,
ctx
->
framebuffer_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
ctx
->
fd
,
0
);
if
(
ctx
->
framebuffer_addr
==
MAP_FAILED
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
return
NULL
;
}
}
ctx
->
blt2d
.
self
=
ctx
;
ctx
->
blt2d
.
overlapped_blt
=
fb_copyarea_blt
;
return
ctx
;
}
void
fb_copyarea_close
(
fb_copyarea_t
*
ctx
)
{
close
(
ctx
->
fd
);
free
(
ctx
);
}
static
inline
int
try_fallback_blt
(
void
*
self
,
uint32_t
*
src_bits
,
uint32_t
*
dst_bits
,
int
src_stride
,
int
dst_stride
,
int
src_bpp
,
int
dst_bpp
,
int
src_x
,
int
src_y
,
int
dst_x
,
int
dst_y
,
int
w
,
int
h
)
{
fb_copyarea_t
*
ctx
=
(
fb_copyarea_t
*
)
self
;
if
(
ctx
->
fallback_blt2d
)
return
ctx
->
fallback_blt2d
->
overlapped_blt
(
ctx
->
fallback_blt2d
->
self
,
src_bits
,
dst_bits
,
src_stride
,
dst_stride
,
src_bpp
,
dst_bpp
,
src_x
,
src_y
,
dst_x
,
dst_y
,
w
,
h
);
return
0
;
}
#define FALLBACK_BLT() try_fallback_blt(self, src_bits, \
dst_bits, src_stride, \
dst_stride, src_bpp, \
dst_bpp, src_x, src_y, \
dst_x, dst_y, w, h);
int
fb_copyarea_blt
(
void
*
self
,
uint32_t
*
src_bits
,
uint32_t
*
dst_bits
,
int
src_stride
,
int
dst_stride
,
int
src_bpp
,
int
dst_bpp
,
int
src_x
,
int
src_y
,
int
dst_x
,
int
dst_y
,
int
w
,
int
h
)
{
fb_copyarea_t
*
ctx
=
(
fb_copyarea_t
*
)
self
;
struct
fb_copyarea
copyarea
;
uint32_t
*
framebuffer_addr
=
(
uint32_t
*
)
ctx
->
framebuffer_addr
;
/* Zero size blit, nothing to do */
if
(
w
<=
0
||
h
<=
0
)
return
1
;
if
(
src_bpp
!=
dst_bpp
||
src_bpp
!=
ctx
->
bits_per_pixel
||
src_stride
!=
dst_stride
||
src_stride
!=
ctx
->
framebuffer_stride
||
src_bits
!=
dst_bits
||
src_bits
!=
framebuffer_addr
)
{
return
FALLBACK_BLT
();
}
copyarea
.
sx
=
src_x
;
copyarea
.
sy
=
src_y
;
copyarea
.
dx
=
dst_x
;
copyarea
.
dy
=
dst_y
;
copyarea
.
width
=
w
;
copyarea
.
height
=
h
;
return
ioctl
(
ctx
->
fd
,
FBIOCOPYAREA
,
&
copyarea
)
==
0
;
}
src/fb_copyarea.h
0 → 100644
View file @
4995422b
/*
* Copyright © 2013 Siarhei Siamashka <siarhei.siamashka@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef FB_COPYAREA_H
#define FB_COPYAREA_H
#include "interfaces.h"
typedef
struct
{
/* framebuffer descriptor */
int
fd
;
int
xres
,
yres
,
bits_per_pixel
;
uint8_t
*
framebuffer_addr
;
/* mmapped address */
uintptr_t
framebuffer_paddr
;
/* physical address */
uint32_t
framebuffer_size
;
/* total size of the framebuffer */
int
framebuffer_height
;
/* virtual vertical resolution */
int
framebuffer_stride
;
uint32_t
gfx_layer_size
;
/* the size of the primary layer */
uint8_t
*
xserver_fbmem
;
/* framebuffer mapping done by xserver */
/* fb_copyarea accelerated implementation of blt2d_i interface */
blt2d_i
blt2d
;
/* Optional fallback interface to handle unsupported operations */
blt2d_i
*
fallback_blt2d
;
}
fb_copyarea_t
;
fb_copyarea_t
*
fb_copyarea_init
(
const
char
*
fb_device
,
void
*
xserver_fbmem
);
void
fb_copyarea_close
(
fb_copyarea_t
*
fb_copyarea
);
int
fb_copyarea_blt
(
void
*
self
,
uint32_t
*
src_bits
,
uint32_t
*
dst_bits
,
int
src_stride
,
int
dst_stride
,
int
src_bpp
,
int
dst_bpp
,
int
src_x
,
int
src_y
,
int
dst_x
,
int
dst_y
,
int
w
,
int
h
);
#endif
src/fbdev.c
View file @
4995422b
...
...
@@ -47,6 +47,7 @@
#include "dgaproc.h"
#include "cpu_backend.h"
#include "fb_copyarea.h"
#include "sunxi_disp.h"
#include "sunxi_disp_hwcursor.h"
...
...
@@ -907,9 +908,13 @@ FBDevScreenInit(SCREEN_INIT_ARGS_DECL)
fPtr
->
sunxi_disp_private
=
sunxi_disp_init
(
xf86FindOptionValue
(
fPtr
->
pEnt
->
device
->
options
,
"fbdev"
),
fPtr
->
fbmem
);
if
(
!
fPtr
->
sunxi_disp_private
)
if
(
!
fPtr
->
sunxi_disp_private
)
{
xf86DrvMsg
(
pScrn
->
scrnIndex
,
X_INFO
,
"failed to enable the use of sunxi display controller
\n
"
);
fPtr
->
fb_copyarea_private
=
fb_copyarea_init
(
xf86FindOptionValue
(
fPtr
->
pEnt
->
device
->
options
,
"fbdev"
),
fPtr
->
fbmem
);
}
if
(
!
(
accelmethod
=
xf86GetOptValString
(
fPtr
->
Options
,
OPTION_ACCELMETHOD
))
||
strcasecmp
(
accelmethod
,
"g2d"
)
==
0
)
{
...
...
@@ -931,6 +936,15 @@ FBDevScreenInit(SCREEN_INIT_ARGS_DECL)
"G2D acceleration is disabled via AccelMethod option
\n
"
);
}
if
(
!
fPtr
->
SunxiG2D_private
&&
fPtr
->
fb_copyarea_private
)
{
fb_copyarea_t
*
fb
=
fPtr
->
fb_copyarea_private
;
if
((
fPtr
->
SunxiG2D_private
=
SunxiG2D_Init
(
pScreen
,
&
fb
->
blt2d
)))
{
fb
->
fallback_blt2d
=
&
cpu_backend
->
blt2d
;
xf86DrvMsg
(
pScrn
->
scrnIndex
,
X_INFO
,
"enabled fbdev copyarea acceleration
\n
"
);
}
}
if
(
!
fPtr
->
SunxiG2D_private
&&
cpu_backend
->
cpuinfo
->
has_arm_vfp
)
{
if
((
fPtr
->
SunxiG2D_private
=
SunxiG2D_Init
(
pScreen
,
&
cpu_backend
->
blt2d
)))
{
xf86DrvMsg
(
pScrn
->
scrnIndex
,
X_INFO
,
"enabled VFP/NEON optimizations
\n
"
);
...
...
@@ -1100,6 +1114,10 @@ FBDevCloseScreen(CLOSE_SCREEN_ARGS_DECL)
free
(
fPtr
->
SunxiG2D_private
);
fPtr
->
SunxiG2D_private
=
NULL
;
}
if
(
fPtr
->
fb_copyarea_private
)
{
fb_copyarea_close
(
fPtr
->
fb_copyarea_private
);
fPtr
->
fb_copyarea_private
=
NULL
;
}
if
(
fPtr
->
sunxi_disp_private
)
{
sunxi_disp_close
(
fPtr
->
sunxi_disp_private
);
fPtr
->
sunxi_disp_private
=
NULL
;
...
...
src/fbdev_priv.h
View file @
4995422b
...
...
@@ -56,7 +56,8 @@ typedef struct {
void
*
cpu_backend_private
;
void
*
backing_store_tuner_private
;
void
*
sunxi_disp_private
;;
void
*
sunxi_disp_private
;
void
*
fb_copyarea_private
;
void
*
SunxiDispHardwareCursor_private
;
void
*
SunxiMaliDRI2_private
;
void
*
SunxiG2D_private
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment