mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-14 09:42:10 -04:00
screenshot: flip bits for RGB888
This commit is contained in:
@@ -30,6 +30,7 @@ type Output struct {
|
|||||||
height int32
|
height int32
|
||||||
scale int32
|
scale int32
|
||||||
fractionalScale float64
|
fractionalScale float64
|
||||||
|
transform int32
|
||||||
}
|
}
|
||||||
|
|
||||||
type LayerSurface struct {
|
type LayerSurface struct {
|
||||||
@@ -276,6 +277,7 @@ func (p *Picker) setupOutputHandlers(name uint32, output *client.Output) {
|
|||||||
if o, ok := p.outputs[name]; ok {
|
if o, ok := p.outputs[name]; ok {
|
||||||
o.x = e.X
|
o.x = e.X
|
||||||
o.y = e.Y
|
o.y = e.Y
|
||||||
|
o.transform = int32(e.Transform)
|
||||||
}
|
}
|
||||||
p.outputsMu.Unlock()
|
p.outputsMu.Unlock()
|
||||||
})
|
})
|
||||||
@@ -485,8 +487,19 @@ func (p *Picker) captureForSurface(ls *LayerSurface) {
|
|||||||
frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) {
|
frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) {
|
||||||
ls.state.OnScreencopyReady()
|
ls.state.OnScreencopyReady()
|
||||||
|
|
||||||
logicalW, _ := ls.state.LogicalSize()
|
|
||||||
screenBuf := ls.state.ScreenBuffer()
|
screenBuf := ls.state.ScreenBuffer()
|
||||||
|
if screenBuf != nil && ls.output.transform != TransformNormal {
|
||||||
|
invTransform := InverseTransform(ls.output.transform)
|
||||||
|
transformed, err := screenBuf.ApplyTransform(invTransform)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("apply transform failed", "err", err)
|
||||||
|
} else if transformed != screenBuf {
|
||||||
|
ls.state.ReplaceScreenBuffer(transformed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logicalW, _ := ls.state.LogicalSize()
|
||||||
|
screenBuf = ls.state.ScreenBuffer()
|
||||||
if logicalW > 0 && screenBuf != nil {
|
if logicalW > 0 && screenBuf != nil {
|
||||||
ls.output.fractionalScale = float64(screenBuf.Width) / float64(logicalW)
|
ls.output.fractionalScale = float64(screenBuf.Width) / float64(logicalW)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,25 @@ import "github.com/AvengeMedia/DankMaterialShell/core/internal/wayland/shm"
|
|||||||
|
|
||||||
type ShmBuffer = shm.Buffer
|
type ShmBuffer = shm.Buffer
|
||||||
|
|
||||||
|
const (
|
||||||
|
TransformNormal = shm.TransformNormal
|
||||||
|
Transform90 = shm.Transform90
|
||||||
|
Transform180 = shm.Transform180
|
||||||
|
Transform270 = shm.Transform270
|
||||||
|
TransformFlipped = shm.TransformFlipped
|
||||||
|
TransformFlipped90 = shm.TransformFlipped90
|
||||||
|
TransformFlipped180 = shm.TransformFlipped180
|
||||||
|
TransformFlipped270 = shm.TransformFlipped270
|
||||||
|
)
|
||||||
|
|
||||||
func CreateShmBuffer(width, height, stride int) (*ShmBuffer, error) {
|
func CreateShmBuffer(width, height, stride int) (*ShmBuffer, error) {
|
||||||
return shm.CreateBuffer(width, height, stride)
|
return shm.CreateBuffer(width, height, stride)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InverseTransform(transform int32) int32 {
|
||||||
|
return shm.InverseTransform(transform)
|
||||||
|
}
|
||||||
|
|
||||||
func GetPixelColor(buf *ShmBuffer, x, y int) Color {
|
func GetPixelColor(buf *ShmBuffer, x, y int) Color {
|
||||||
return GetPixelColorWithFormat(buf, x, y, FormatARGB8888)
|
return GetPixelColorWithFormat(buf, x, y, FormatARGB8888)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,20 @@ func (s *SurfaceState) ScreenFormat() PixelFormat {
|
|||||||
return s.screenFormat
|
return s.screenFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SurfaceState) ReplaceScreenBuffer(newBuf *ShmBuffer) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
if s.screenBuf != nil {
|
||||||
|
s.screenBuf.Close()
|
||||||
|
}
|
||||||
|
s.screenBuf = newBuf
|
||||||
|
s.screenFormat = newBuf.Format
|
||||||
|
|
||||||
|
s.recomputeScale()
|
||||||
|
s.ensureRenderBuffers()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SurfaceState) OnScreencopyFlags(flags uint32) {
|
func (s *SurfaceState) OnScreencopyFlags(flags uint32) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
s.yInverted = (flags & 1) != 0
|
s.yInverted = (flags & 1) != 0
|
||||||
|
|||||||
@@ -109,7 +109,11 @@ func (b *Buffer) ConvertTo32Bit(srcFormat PixelFormat) (*Buffer, PixelFormat, er
|
|||||||
|
|
||||||
srcData := b.data
|
srcData := b.data
|
||||||
dstData := dst.data
|
dstData := dst.data
|
||||||
isRGB := srcFormat == FormatRGB888
|
|
||||||
|
// DRM format names are counterintuitive on little-endian:
|
||||||
|
// RGB888 memory layout: B, G, R (name is logical order, not memory)
|
||||||
|
// BGR888 memory layout: R, G, B
|
||||||
|
isBGRMemory := srcFormat == FormatRGB888
|
||||||
|
|
||||||
for y := 0; y < b.Height; y++ {
|
for y := 0; y < b.Height; y++ {
|
||||||
srcRow := y * b.Stride
|
srcRow := y * b.Stride
|
||||||
@@ -117,14 +121,16 @@ func (b *Buffer) ConvertTo32Bit(srcFormat PixelFormat) (*Buffer, PixelFormat, er
|
|||||||
for x := 0; x < b.Width; x++ {
|
for x := 0; x < b.Width; x++ {
|
||||||
si := srcRow + x*3
|
si := srcRow + x*3
|
||||||
di := dstRow + x*4
|
di := dstRow + x*4
|
||||||
if isRGB {
|
if isBGRMemory {
|
||||||
dstData[di+0] = srcData[si+2] // B
|
// RGB888: src memory is B,G,R -> dst XRGB8888 memory B,G,R,X
|
||||||
dstData[di+1] = srcData[si+1] // G
|
dstData[di+0] = srcData[si+0]
|
||||||
dstData[di+2] = srcData[si+0] // R
|
dstData[di+1] = srcData[si+1]
|
||||||
|
dstData[di+2] = srcData[si+2]
|
||||||
} else {
|
} else {
|
||||||
dstData[di+0] = srcData[si+0] // B
|
// BGR888: src memory is R,G,B -> dst XRGB8888 memory B,G,R,X
|
||||||
dstData[di+1] = srcData[si+1] // G
|
dstData[di+0] = srcData[si+2]
|
||||||
dstData[di+2] = srcData[si+2] // R
|
dstData[di+1] = srcData[si+1]
|
||||||
|
dstData[di+2] = srcData[si+0]
|
||||||
}
|
}
|
||||||
dstData[di+3] = 0xFF
|
dstData[di+3] = 0xFF
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user