Skip to content

Commit

Permalink
WIP - Use OpenGL for pixel format
Browse files Browse the repository at this point in the history
  • Loading branch information
acolombier committed Sep 26, 2023
1 parent 92690b5 commit 5bb13d1
Show file tree
Hide file tree
Showing 17 changed files with 261 additions and 84 deletions.
28 changes: 14 additions & 14 deletions res/controllers/Dummy Device Screen.hid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@
</info>
<controller id="DummyDevice">
<renderfiles>
<screen filename="Dummy-Device-Default-Screen.qml" identifier="deck" width="320" height="240" screenCount="2" targetFps="50">
<screen filename="Dummy-Device-Default-Screen.qml" identifier="deck" width="320" height="240" screenCount="1" targetFps="40" pixelType="RBG565">
<library path="Dummy-Device-Default-Screen" />
<transformfunction type="javascript">
(function(input, screen_id) {
data = new Array(320*240*2 + 20).fill(0);
input = new Uint8Array(input);
data[0] = 0x84;
data[3] = 0x21;
data[12] = 0x1;
data[13] = 0x40;
data[15] = 0xf0;
data[320*240*2 + 16] = 0x40;
data[2] = screen_id;
for (var i = 0; i &lt; 320 * 240; i ++){
data[16 + 2 * i] = (input[i * 4] &amp; 0xf8) | (input[i * 4 + 1] >> 5);
data[16 + 2 * i + 1] = (input[i * 4 + 1] &lt;&lt; 3) &amp; 0xe0 | (input[i * 4 + 2] >> 3);
}
data = new ArrayBuffer(320*240*2 + 20);
header = new Uint8Array(data, 0, 16);
payload = new Uint8Array(data, 16, 320*240*2);
footer = new Uint8Array(data, 320*240*2 + 16, 4);
header.fill(0)
footer.fill(0)
header[0] = 0x84;
header[3] = 0x21;
header[12] = 0x1;
header[13] = 0x40;
header[15] = 0xf0;
payload.set(new Uint8Array(input, 0, 320*240*2))
footer[2] = screen_id;
return data;
})
</transformfunction>
Expand Down
5 changes: 2 additions & 3 deletions res/controllers/Dummy-Device-Default-Screen/OnAirTrack.qml
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ Item {
onTriggered: {
if (status == OnAirTrack.TimerStatus.Cooldown) {
status += backward ? -1 : 1
interval = 100
interval = 15
}
frame.x -= backward ? -10 : 10;
// root.text = `${index}${root.fullText.slice(root.index, root.index+29)}`
frame.x -= backward ? -1 : 1;
if (-frame.x >= (text.text.length - 29) * 11) {
backward = true
status = OnAirTrack.TimerStatus.Cooldown
Expand Down
8 changes: 8 additions & 0 deletions res/controllers/Dummy-Device-Default-Screen/Progression.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Item {

width: 0

Mixxx.ControlProxy {
group: root.group
key: "track_loaded"
onValueChanged: (value) => {
root.visible = value
}
}

Mixxx.ControlProxy {
group: root.group
key: "playposition"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ Rectangle {
group: root.group
key: "end_of_track"
onValueChanged: (value) => {
root.border.color = 'red'
root.color = 'red'
root.border.color = value ? 'red' : timeColor
root.color = value ? 'red' : timeColor
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions res/controllers/Traktor Kontrol S4 MK3.bulk.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version='1.0' encoding='utf-8'?>
<MixxxControllerPreset mixxxVersion="2.4.0" schemaVersion="1">
<info>
<name>S4 Mk3 screens</name>
<author>A. Colombier</author>
<description>Dummy device screens</description>
<devices>
<product protocol="bulk" vendor_id="0x17cc" product_id="0x1720" out_epaddr="0x03" />
</devices>
</info>
<controller id="DummyDevice">
<renderfiles>
<screen filename="Dummy-Device-Default-Screen.qml" identifier="deck" width="320" height="240" screenCount="1" targetFps="40" pixelType="RBG565">
<library path="Dummy-Device-Default-Screen" />
<transformfunction type="javascript">
(function(input, screen_id) {
data = new ArrayBuffer(320*240*2 + 20);
header = new Uint8Array(data, 0, 16);
payload = new Uint8Array(data, 16, 320*240*2);
footer = new Uint8Array(data, 320*240*2 + 16, 4);
header.fill(0)
footer.fill(0)
header[0] = 0x84;
header[3] = 0x21;
header[12] = 0x1;
header[13] = 0x40;
header[15] = 0xf0;
payload.set(new Uint8Array(input, 0, 320*240*2))
footer[2] = screen_id;
return data;
})
</transformfunction>
</screen>
</renderfiles>
</controller>
</MixxxControllerPreset>
1 change: 1 addition & 0 deletions src/controllers/bulk/bulksupported.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ static bulk_supported_t bulk_supported[] = {
{0x06f8, 0xb107, 0x83, 0x03}, // Hercules Mk4
{0x06f8, 0xb100, 0x86, 0x06}, // Hercules Mk2
{0x06f8, 0xb120, 0x82, 0x03}, // Hercules MP3 LE / Glow
{0x17cc, 0x1720, 0x00, 0x03}, // Traktor NI S4 Mk3
{0, 0, 0, 0}
};
13 changes: 7 additions & 6 deletions src/controllers/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ void Controller::startEngine()

void Controller::stopEngine() {
qCInfo(m_logBase) << " Shutting down engine";
if (!m_pScriptEngineLegacy) {
qCWarning(m_logBase) << "Controller::stopEngine(): No engine exists!";
return;
}
delete m_pScriptEngineLegacy;
m_pScriptEngineLegacy = nullptr;

for (auto renderer : m_pRenderingEngines) {
if (m_screenDebugManager) {
Expand All @@ -65,6 +59,13 @@ void Controller::stopEngine() {
renderer->stop();
}
m_pRenderingEngines.clear();

if (!m_pScriptEngineLegacy) {
qCWarning(m_logBase) << "Controller::stopEngine(): No engine exists!";
return;
}
delete m_pScriptEngineLegacy;
m_pScriptEngineLegacy = nullptr;
}

bool Controller::applyMapping() {
Expand Down
14 changes: 11 additions & 3 deletions src/controllers/controllermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,23 @@ void DebugControllerScreens::addRenderer(
// TODO assert
auto screen = m_debugsScreens.value(renderer.get());
if (screen) {
screen->setText(mixxx::Time::elapsed().formatMillisWithUnit());
// screen->setText(mixxx::Time::elapsed().formatMillisWithUnit());
screen->setPixmap(QPixmap::fromImage(frame));
}
}
// TODO disconnect?
// else {

// }
});
}

void DebugControllerScreens::removeRenderer(std::shared_ptr<ControllerRenderingEngine> renderer) {
VERIFY_OR_DEBUG_ASSERT(renderer.get()) {
return;
}
m_debugsScreens.take(renderer.get()).reset();
auto screen = m_debugsScreens.take(renderer.get());
screen->hide();
screen.reset();
}

ControllerManager::ControllerManager(UserSettingsPointer pConfig)
Expand Down Expand Up @@ -296,6 +302,8 @@ void ControllerManager::slotSetUpDevices() {
continue;
}

pController->setScreenDebugController(m_debugScreen);

qDebug() << "Searching for controller mapping" << mappingFilePath
<< "in paths:" << mappingPaths.join(",");
QFileInfo mappingFile = findMappingFile(mappingFilePath, mappingPaths);
Expand Down
19 changes: 10 additions & 9 deletions src/controllers/hid/hidiooutputreport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ bool HidIoOutputReport::sendCachedData(QMutex* pHidDeviceAndPollMutex,

cacheLock.unlock();

qCDebug(logOutput) << "t:" << startOfHidWrite.formatMillisWithUnit()
<< "Skipped sending identical OutputReport data from cache for ReportID"
<< m_reportId;
// qCDebug(logOutput) << "t:" << startOfHidWrite.formatMillisWithUnit()
// << "Skipped sending identical OutputReport data
// from cache for ReportID"
// << m_reportId;

// Return with false, to signal the caller, that no time consuming IO operation was necessary
return false;
Expand All @@ -122,12 +123,12 @@ bool HidIoOutputReport::sendCachedData(QMutex* pHidDeviceAndPollMutex,
int result = hid_write(pHidDevice,
reinterpret_cast<const unsigned char*>(m_lastSentData.constData()),
m_lastSentData.size());
if (result == -1) {
qCWarning(logOutput) << "Unable to send data to device :"
<< mixxx::convertWCStringToQString(
hid_error(pHidDevice),
kMaxHidErrorMessageSize);
}
// if (result == -1) {
// qCWarning(logOutput) << "Unable to send data to device :"
// << mixxx::convertWCStringToQString(
// hid_error(pHidDevice),
// kMaxHidErrorMessageSize);
// }

hidDeviceLock.unlock();

Expand Down
6 changes: 6 additions & 0 deletions src/controllers/legacycontrollermapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QSize>
#include <QString>
#include <memory>
#include <QOpenGLContext>

#include "controllers/rendering/controllerrenderingtransform.h"
#include "defs_urls.h"
Expand Down Expand Up @@ -39,6 +40,7 @@ class LegacyControllerMapping {
const QSize& aSize,
uint8_t aScreen_count,
uint8_t aTarget_fps,
GLenum aPixelFormat,
const QFileInfo& aFile,
const QList<QFileInfo>& aLibraryList,
const QString& transformPayload,
Expand All @@ -47,6 +49,7 @@ class LegacyControllerMapping {
size(aSize),
screen_count(aScreen_count),
target_fps(aTarget_fps),
pixelFormat(aPixelFormat),
file(aFile),
libraries(aLibraryList),
transformFunctionPayload(transformPayload),
Expand All @@ -57,6 +60,7 @@ class LegacyControllerMapping {
QSize size;
uint8_t screen_count;
uint8_t target_fps;
GLenum pixelFormat;
QFileInfo file;
QList<QFileInfo> libraries;

Expand Down Expand Up @@ -98,6 +102,7 @@ class LegacyControllerMapping {
const QString& transformPayload,
uint8_t screenCount = 1,
uint8_t targetFps = 30,
GLenum pixelFormat = GL_UNSIGNED_BYTE,
ControllerRenderingTransformFunctionType transformType =
ControllerRenderingTransformFunctionType::NONE) {
if (!targetFps) {
Expand All @@ -110,6 +115,7 @@ class LegacyControllerMapping {
size,
screenCount,
targetFps,
pixelFormat,
file,
libraries,
transformPayload,
Expand Down
14 changes: 14 additions & 0 deletions src/controllers/legacycontrollermappingfilehandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ QFileInfo findLibraryPath(std::shared_ptr<LegacyControllerMapping> mapping,

} // namespace

QMap<QString,GLenum> LegacyControllerMappingFileHandler::kSupportedPixelFormat = {
{"RBGA8888", GL_UNSIGNED_INT},
{"RBG565", GL_UNSIGNED_SHORT_5_6_5_REV},
};

// static
std::shared_ptr<LegacyControllerMapping> LegacyControllerMappingFileHandler::loadMapping(
const QFileInfo& mappingFile, const QDir& systemMappingsPath) {
Expand Down Expand Up @@ -174,6 +179,14 @@ void LegacyControllerMappingFileHandler::addScriptFilesToMapping(
QString identifier = screenDef.attribute("filename", "");
uint8_t screenCount = screenDef.attribute("screenCount", "1").toUInt();
uint8_t targetFps = screenDef.attribute("targetFps", "1").toUInt();
QString pixelFormatName = screenDef.attribute("pixelType", "RBG888");

if (!kSupportedPixelFormat.contains(pixelFormatName)){
qWarning() << "Unsupported pixel format" << pixelFormatName;
continue;
}

GLenum pixelFormat = kSupportedPixelFormat.value(pixelFormatName);

uint width = screenDef.attribute("width", "0").toUInt();
uint height = screenDef.attribute("height", "0").toUInt();
Expand Down Expand Up @@ -223,6 +236,7 @@ void LegacyControllerMappingFileHandler::addScriptFilesToMapping(
transformPayload,
screenCount,
targetFps,
pixelFormat,
transformType);
screenDef = screenDef.nextSiblingElement("screen");
}
Expand Down
5 changes: 5 additions & 0 deletions src/controllers/legacycontrollermappingfilehandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "controllers/legacycontrollermapping.h"
#include "util/xml.h"
#include <QOpenGLContext>
#include <QMap>

/// The LegacyControllerMappingFileHandler is used for serializing/deserializing the
/// LegacyControllerMapping objects to/from XML files and is also responsible
Expand Down Expand Up @@ -60,4 +62,7 @@ class LegacyControllerMappingFileHandler {
virtual std::shared_ptr<LegacyControllerMapping> load(const QDomElement& root,
const QString& filePath,
const QDir& systemMappingPath) = 0;

static QMap<QString,GLenum> kSupportedPixelFormat;

};
Loading

0 comments on commit 5bb13d1

Please sign in to comment.