github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/exp/shiny/driver/windriver/buffer.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build windows
     6  
     7  package windriver
     8  
     9  import (
    10  	"image"
    11  	"sync"
    12  	"syscall"
    13  
    14  	"golang.org/x/exp/shiny/driver/internal/swizzle"
    15  )
    16  
    17  type bufferImpl struct {
    18  	hbitmap syscall.Handle
    19  	buf     []byte
    20  	rgba    image.RGBA
    21  	size    image.Point
    22  
    23  	mu        sync.Mutex
    24  	nUpload   uint32
    25  	reusable  bool
    26  	released  bool
    27  	cleanedUp bool
    28  }
    29  
    30  func (b *bufferImpl) Size() image.Point       { return b.size }
    31  func (b *bufferImpl) Bounds() image.Rectangle { return image.Rectangle{Max: b.size} }
    32  func (b *bufferImpl) RGBA() *image.RGBA       { return &b.rgba }
    33  
    34  func (b *bufferImpl) preUpload(reusable bool) {
    35  	b.mu.Lock()
    36  	defer b.mu.Unlock()
    37  
    38  	if b.released {
    39  		panic("windriver: Buffer.Upload called after Buffer.Release")
    40  	}
    41  	if b.nUpload == 0 {
    42  		swizzle.BGRA(b.buf)
    43  	}
    44  	b.nUpload++
    45  	b.reusable = b.reusable && reusable
    46  }
    47  
    48  func (b *bufferImpl) postUpload() {
    49  	b.mu.Lock()
    50  	defer b.mu.Unlock()
    51  
    52  	b.nUpload--
    53  	if b.nUpload != 0 {
    54  		return
    55  	}
    56  
    57  	if b.released {
    58  		go b.cleanUp()
    59  	} else if b.reusable {
    60  		swizzle.BGRA(b.buf)
    61  	}
    62  }
    63  
    64  func (b *bufferImpl) Release() {
    65  	b.mu.Lock()
    66  	defer b.mu.Unlock()
    67  
    68  	if !b.released && b.nUpload == 0 {
    69  		go b.cleanUp()
    70  	}
    71  	b.released = true
    72  }
    73  
    74  func (b *bufferImpl) cleanUp() {
    75  	b.mu.Lock()
    76  	if b.cleanedUp {
    77  		b.mu.Unlock()
    78  		panic("windriver: Buffer clean-up occurred twice")
    79  	}
    80  	b.cleanedUp = true
    81  	b.mu.Unlock()
    82  
    83  	b.rgba.Pix = nil
    84  	_DeleteObject(b.hbitmap)
    85  }