2 * Copyright (C) 2010 David McPaul
4 * All rights reserved. Distributed under the terms of the MIT License.
7 // This class merges buffers together
8 // Merge is called everytime a primary buffer needs to be passed downstream
9 // This should allow different framerates to be handled by buffering slower
10 // buffer producers and discarding buffers from faster producers
11 // TODO ColorConversion
13 #include "BufferMixer.h"
15 BufferMixer::BufferMixer() {
18 BufferMixer::~BufferMixer() {
22 BufferMixer::isBufferAvailable() {
23 return groupedBuffers
[0] != NULL
;
26 // Should only be called after checking with isBufferAvailable
28 BufferMixer::GetOutputBuffer() {
29 // Do the merging of all buffers in the groupedBuffers map
30 // into the primary buffer and return that buffer.
31 // The primary buffer is removed;
33 BBuffer
*outputBuffer
= groupedBuffers
[0];
34 groupedBuffers
[0] = NULL
;
36 std::map
<int32
, BBuffer
*>::iterator each
;
38 for (each
=groupedBuffers
.begin(); each
!= groupedBuffers
.end(); each
++) {
39 if (each
->second
!= outputBuffer
) {
40 if (each
->second
!= NULL
) {
41 Merge(each
->second
, outputBuffer
);
49 #define ALPHABLEND(source, destination, alpha) (((destination) * (256 - (alpha)) + (source) * (alpha)) >> 8)
52 BufferMixer::Merge(BBuffer
*input
, BBuffer
*output
) {
53 // Currently only deals with RGBA32
55 uint8
*source
= (uint8
*)input
->Data();
56 uint8
*destination
= (uint8
*)output
->Data();
57 uint32 size
= input
->Header()->size_used
/ 4;
61 for (uint32 i
=0; i
<size
; i
++) {
66 destination
[0] = ALPHABLEND(c1
, destination
[0], alpha
);
67 destination
[1] = ALPHABLEND(c2
, destination
[1], alpha
);
68 destination
[2] = ALPHABLEND(c3
, destination
[2], alpha
);
69 destination
[3] = 0x00;
75 BufferMixer::AddBuffer(int32 id
, BBuffer
*buffer
, bool isPrimary
) {
79 oldBuffer
= groupedBuffers
[0];
80 groupedBuffers
[0] = buffer
;
82 oldBuffer
= groupedBuffers
[id
];
83 groupedBuffers
[id
] = buffer
;
86 if (oldBuffer
!= NULL
) {
92 BufferMixer::RemoveBuffer(int32 id
) {
95 if (uint32(id
) < groupedBuffers
.size()) {
96 oldBuffer
= groupedBuffers
[id
];
97 groupedBuffers
[id
] = NULL
;
99 if (oldBuffer
!= NULL
) {
100 oldBuffer
->Recycle();