Changeset View
Changeset View
Standalone View
Standalone View
platformsupport/scenes/opengl/abstract_egl_backend.cpp
Show First 20 Lines • Show All 338 Lines • ▼ Show 20 Line(s) | |||||
339 | 339 | | |||
340 | OpenGLBackend *AbstractEglTexture::backend() | 340 | OpenGLBackend *AbstractEglTexture::backend() | ||
341 | { | 341 | { | ||
342 | return m_backend; | 342 | return m_backend; | ||
343 | } | 343 | } | ||
344 | 344 | | |||
345 | bool AbstractEglTexture::loadTexture(WindowPixmap *pixmap) | 345 | bool AbstractEglTexture::loadTexture(WindowPixmap *pixmap) | ||
346 | { | 346 | { | ||
347 | // FIXME: Refactor this method. | ||||
348 | | ||||
347 | const auto &buffer = pixmap->buffer(); | 349 | const auto &buffer = pixmap->buffer(); | ||
348 | if (buffer.isNull()) { | 350 | if (buffer.isNull()) { | ||
349 | if (updateFromFBO(pixmap->fbo())) { | 351 | if (updateFromFBO(pixmap->fbo())) { | ||
350 | return true; | 352 | return true; | ||
351 | } | 353 | } | ||
354 | if (loadInternalImageObject(pixmap)) { | ||||
355 | return true; | ||||
356 | } | ||||
352 | return false; | 357 | return false; | ||
353 | } | 358 | } | ||
354 | // try Wayland loading | 359 | // try Wayland loading | ||
355 | if (auto s = pixmap->surface()) { | 360 | if (auto s = pixmap->surface()) { | ||
356 | s->resetTrackedDamage(); | 361 | s->resetTrackedDamage(); | ||
357 | } | 362 | } | ||
358 | if (buffer->linuxDmabufBuffer()) { | 363 | if (buffer->linuxDmabufBuffer()) { | ||
359 | return loadDmabufTexture(buffer); | 364 | return loadDmabufTexture(buffer); | ||
360 | } else if (buffer->shmBuffer()) { | 365 | } else if (buffer->shmBuffer()) { | ||
361 | return loadShmTexture(buffer); | 366 | return loadShmTexture(buffer); | ||
362 | } | 367 | } | ||
363 | return loadEglTexture(buffer); | 368 | return loadEglTexture(buffer); | ||
364 | } | 369 | } | ||
365 | 370 | | |||
366 | void AbstractEglTexture::updateTexture(WindowPixmap *pixmap) | 371 | void AbstractEglTexture::updateTexture(WindowPixmap *pixmap) | ||
367 | { | 372 | { | ||
373 | // FIXME: Refactor this method. | ||||
374 | | ||||
368 | const auto &buffer = pixmap->buffer(); | 375 | const auto &buffer = pixmap->buffer(); | ||
369 | if (buffer.isNull()) { | 376 | if (buffer.isNull()) { | ||
370 | const auto &fbo = pixmap->fbo(); | 377 | if (updateFromFBO(pixmap->fbo())) { | ||
371 | if (!fbo.isNull()) { | 378 | return; | ||
372 | if (m_texture != fbo->texture()) { | | |||
373 | updateFromFBO(fbo); | | |||
374 | } | 379 | } | ||
380 | if (updateFromInternalImageObject(pixmap)) { | ||||
375 | return; | 381 | return; | ||
376 | } | 382 | } | ||
377 | return; | 383 | return; | ||
378 | } | 384 | } | ||
379 | auto s = pixmap->surface(); | 385 | auto s = pixmap->surface(); | ||
380 | if (DmabufBuffer *dmabuf = static_cast<DmabufBuffer *>(buffer->linuxDmabufBuffer())) { | 386 | if (DmabufBuffer *dmabuf = static_cast<DmabufBuffer *>(buffer->linuxDmabufBuffer())) { | ||
381 | q->bind(); | 387 | q->bind(); | ||
382 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES) dmabuf->images()[0]); //TODO | 388 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES) dmabuf->images()[0]); //TODO | ||
▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Line(s) | 540 | { | |||
549 | q->unbind(); | 555 | q->unbind(); | ||
550 | 556 | | |||
551 | m_size = dmabuf->size(); | 557 | m_size = dmabuf->size(); | ||
552 | q->setYInverted(!(dmabuf->flags() & KWayland::Server::LinuxDmabufUnstableV1Interface::YInverted)); | 558 | q->setYInverted(!(dmabuf->flags() & KWayland::Server::LinuxDmabufUnstableV1Interface::YInverted)); | ||
553 | 559 | | |||
554 | return true; | 560 | return true; | ||
555 | } | 561 | } | ||
556 | 562 | | |||
563 | bool AbstractEglTexture::loadInternalImageObject(WindowPixmap *pixmap) | ||||
564 | { | ||||
565 | // FIXME: Share some code with loadShmTexture(). | ||||
566 | | ||||
567 | const QImage image = pixmap->internalImage(); | ||||
568 | if (image.isNull()) { | ||||
569 | return false; | ||||
570 | } | ||||
571 | | ||||
572 | glGenTextures(1, &m_texture); | ||||
573 | q->setFilter(GL_LINEAR); | ||||
574 | q->setWrapMode(GL_CLAMP_TO_EDGE); | ||||
575 | q->setYInverted(true); | ||||
576 | q->bind(); | ||||
577 | | ||||
578 | const QSize &size = image.size(); | ||||
579 | // TODO: this should be shared with GLTexture(const QImage&, GLenum) | ||||
580 | GLenum format = 0; | ||||
581 | switch (image.format()) { | ||||
582 | case QImage::Format_ARGB32: | ||||
583 | case QImage::Format_ARGB32_Premultiplied: | ||||
584 | format = GL_RGBA8; | ||||
585 | break; | ||||
586 | case QImage::Format_RGB32: | ||||
587 | format = GL_RGB8; | ||||
588 | break; | ||||
589 | default: | ||||
590 | return false; | ||||
591 | } | ||||
592 | if (GLPlatform::instance()->isGLES()) { | ||||
593 | if (s_supportsARGB32 && format == GL_RGBA8) { | ||||
594 | const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | ||||
595 | glTexImage2D(m_target, 0, GL_BGRA_EXT, im.width(), im.height(), | ||||
596 | 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.bits()); | ||||
597 | } else { | ||||
598 | const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied); | ||||
599 | glTexImage2D(m_target, 0, GL_RGBA, im.width(), im.height(), | ||||
600 | 0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits()); | ||||
601 | } | ||||
602 | } else { | ||||
603 | glTexImage2D(m_target, 0, format, size.width(), size.height(), 0, | ||||
604 | GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); | ||||
605 | } | ||||
606 | | ||||
607 | q->unbind(); | ||||
608 | | ||||
609 | m_size = size; | ||||
610 | updateMatrix(); | ||||
611 | | ||||
612 | return true; | ||||
613 | } | ||||
614 | | ||||
557 | EGLImageKHR AbstractEglTexture::attach(const QPointer< KWayland::Server::BufferInterface > &buffer) | 615 | EGLImageKHR AbstractEglTexture::attach(const QPointer< KWayland::Server::BufferInterface > &buffer) | ||
558 | { | 616 | { | ||
559 | EGLint format, yInverted; | 617 | EGLint format, yInverted; | ||
560 | eglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), EGL_TEXTURE_FORMAT, &format); | 618 | eglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), EGL_TEXTURE_FORMAT, &format); | ||
561 | if (format != EGL_TEXTURE_RGB && format != EGL_TEXTURE_RGBA) { | 619 | if (format != EGL_TEXTURE_RGB && format != EGL_TEXTURE_RGBA) { | ||
562 | qCDebug(KWIN_OPENGL) << "Unsupported texture format: " << format; | 620 | qCDebug(KWIN_OPENGL) << "Unsupported texture format: " << format; | ||
563 | return EGL_NO_IMAGE_KHR; | 621 | return EGL_NO_IMAGE_KHR; | ||
564 | } | 622 | } | ||
Show All 26 Lines | 644 | { | |||
591 | m_size = fbo->size(); | 649 | m_size = fbo->size(); | ||
592 | q->setWrapMode(GL_CLAMP_TO_EDGE); | 650 | q->setWrapMode(GL_CLAMP_TO_EDGE); | ||
593 | q->setFilter(GL_LINEAR); | 651 | q->setFilter(GL_LINEAR); | ||
594 | q->setYInverted(false); | 652 | q->setYInverted(false); | ||
595 | updateMatrix(); | 653 | updateMatrix(); | ||
596 | return true; | 654 | return true; | ||
597 | } | 655 | } | ||
598 | 656 | | |||
657 | bool AbstractEglTexture::updateFromInternalImageObject(WindowPixmap *pixmap) | ||||
658 | { | ||||
659 | // FIXME: Share some code with the shm fallback in updateTexture(). | ||||
660 | | ||||
661 | const QImage image = pixmap->internalImage(); | ||||
662 | if (image.isNull()) { | ||||
663 | return false; | ||||
664 | } | ||||
665 | | ||||
666 | if (m_size != image.size()) { | ||||
667 | glDeleteTextures(1, &m_texture); | ||||
668 | return loadInternalImageObject(pixmap); | ||||
669 | } | ||||
670 | | ||||
671 | const QRegion damage = pixmap->toplevel()->damage(); | ||||
672 | const qreal scale = image.devicePixelRatio(); | ||||
673 | | ||||
674 | q->bind(); | ||||
675 | | ||||
676 | // TODO: this should be shared with GLTexture::update | ||||
677 | if (GLPlatform::instance()->isGLES()) { | ||||
678 | if (s_supportsARGB32 && (image.format() == QImage::Format_ARGB32 || image.format() == QImage::Format_ARGB32_Premultiplied)) { | ||||
679 | const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | ||||
680 | for (const QRect &rect : damage) { | ||||
681 | auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale); | ||||
682 | glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(), | ||||
683 | GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits()); | ||||
684 | } | ||||
685 | } else { | ||||
686 | const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied); | ||||
687 | for (const QRect &rect : damage) { | ||||
688 | auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale); | ||||
689 | glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(), | ||||
690 | GL_RGBA, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits()); | ||||
691 | } | ||||
692 | } | ||||
693 | } else { | ||||
694 | const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | ||||
695 | for (const QRect &rect : damage) { | ||||
696 | auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale); | ||||
697 | glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(), | ||||
698 | GL_BGRA, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits()); | ||||
699 | } | ||||
700 | } | ||||
701 | | ||||
702 | q->unbind(); | ||||
703 | | ||||
704 | return true; | ||||
705 | } | ||||
706 | | ||||
599 | } | 707 | } | ||
600 | 708 | |