aboutsummaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote-tracking branch 'origin/5.13' into devQt Forward Merge Bot2019-08-206-52/+109
|\ | | | | | | Change-Id: I9ce3eee3d6f88783b9e20110a2814bee805291a4
| * Doc: Correct error in doc Transition QML TypeNico Vertriest2019-08-193-49/+106
| | | | | | | | | | | | | | | | | | - corrected reference to non-existing state - added example with multiple states Fixes: QTBUG-73982 Change-Id: I7c815cb706f1ad1b8035f136448b75dce8eb9bfe Reviewed-by: Paul Wicking <paul.wicking@qt.io>
| * Doc: Correct wrong code in qml snippetNico Vertriest2019-08-191-1/+1
| | | | | | | | | | | | | | | | | | Replace QT_TRANSLATE_NOOP with equiv. qStr statement Task-number: QTBUG-56875 Change-Id: I80581ecf05a25e0c69da434d3e548261eac5811e Reviewed-by: Frederik Schwarzer <schwarzer@kde.org> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
| * Merge remote-tracking branch 'origin/5.12' into 5.13Liang Qi2019-08-052-2/+2
| |\ | | | | | | | | | Change-Id: I042df89ddd381c7fbb944b7ff49d5b45b764fd47
| | * Fix possible crash with top/bottom aligned imagesEskil Abrahamsen Blomfeldt2019-07-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An image inside at the end of a text block which did not start at text position 0 would resolve to an invalid QTextLine, since we passed the document position to lineForTextPosition(), which expects the relative block position. If the image was aligned to top or bottom, so that the extracted QTextLine was actually accessed, this would cause a crash. [ChangeLog][QtQuick][Text] Fixed a bug where aligning an image to "top" or "bottom" could cause a crash under certain circumstances. Task-number: QTBUG-77217 Change-Id: Iaa239ba482f2a765703656e4116cbebb8435a66e Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| | * Doc: Fix QtQuick.Shapes::ShapePath::strokeWidth property typeLeena Miettinen2019-07-261-1/+1
| | | | | | | | | | | | | | | | | | Fixes: QTBUG-73541 Change-Id: Icb15cee3c49f142ef3634e35427dbbc0b9a2183e Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* | | Introduce functions to set properties during creationFabian Kosmale2019-08-199-11/+109
| | | | | | | | | | | | | | | Change-Id: Idd4c8ab9e34b9bc3e00f21d7cf1e4f1a70586e7f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* | | Fix build without features.qml-delegate-modelTasuku Suzuki2019-08-191-1/+1
| | | | | | | | | | | | | | | Change-Id: I362febbb395e1d6d55d4b4aac18c6e8bba90bb0c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* | | Fix build without features.quick_gridviewTasuku Suzuki2019-08-191-0/+2
| | | | | | | | | | | | | | | | | | Change-Id: I35303ee67d5976c54b5672d0e2333e8533552986 Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* | | Add an initial set of scenegraph docs for the rhiLaszlo Agocs2019-08-175-137/+257
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Just the basics for now. Start moving away of the assumption of default backend = direct OpenGL, but limit the amount of RHI-specific details for now. This should be sufficient for the first preview in 5.14. Change-Id: I94e80d5fbed1269f7e8911284c28ac5fbc858be7 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* | | Rescale on rhi path too when NPoT textures not supportedLaszlo Agocs2019-08-172-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QRhi will not do this for us. Also handle mipmap filtering correctly in this regard. This will fix rendering on WebAssembly. Change-Id: I93a77b7c42bb43c59dfb7748f9fdbd7aa55f39bb Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* | | QSGDepthStencilBufferManager: don't use toStrongRef().data()Marc Mutz2019-08-171-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It's an anti-pattern. Even though we don't expect other threads to destroy the last QSP while we use the pointer obtained from QWeakPointer, play it safe and use QWeakPointer idiomatically: as a non-owning reference, to be converted to an owning one for the duration of our use of the payload object. Add an assertion that explains why we don't expect expired weak_ptrs here. Amends 0f035c0ad79ca41a1473b64a4c0077e7085d3700. Change-Id: Ia39ef5fa243e0e73110aae13da35f4f2ada73a73 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* | | Allow Connections to handle signals using JavaScript functionsUlf Hermann2019-08-163-3/+77
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Requiring full function definitions as signal handlers has two advantages: 1, We don't need a custom parser that magically recognizes properties which would otherwise be an error in other components. 2, The user is forced to specify the full signature of the handler, including any parameters. This helps when the functions will eventually be compiled to C++ The old behavior is retained, generating a warning if any of the magic bindings are still set in a Connections element. Only if no magic bindings are found, the functions are connected. This is because there might be functions named onFoo in old-style Connections elements and silently connecting those to any matching signals would be a change in behavior. Change-Id: I8c78d8994fdcddd355fe822cde9a0702dc8c75de Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Enable threaded render loop for d3d11Laszlo Agocs2019-08-141-10/+13
| | | | | | | | | | | | | | | Change-Id: I5772b38c59b8fe3f9a30f56d3a559f6161443562 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* | | Minor cleanup and logic fix in basic renderloopLaszlo Agocs2019-08-141-7/+10
| | | | | | | | | | | | | | | | | | | | | | | | The (gl) condition is clearly an oversight, the branch should be taken if either gl or rhi are valid. Change-Id: Ieb0a9aeec996f8940716f9fdafe90525b60fc248 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* | | Adapt usage of QMetaCallEvent to changes in QtCoreVolker Hilsheimer2019-08-131-10/+6
| | | | | | | | | | | | | | | | | | | | | Memory allocation is now handled by QMetaCallEvent. Change-Id: I78a2145af6cf93de5e9d71d6b943841f67183fa8 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | scenegraph: fix error: 'QOffscreenSurface' does not name a typeMikko Gronoff2019-08-131-0/+1
| | | | | | | | | | | | | | | Change-Id: I41a8b30b316b038ed1e3910adb0254931f385a2a Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* | | Use QSH::mouseDoubleClickDistance() and touchDoubleTapDistance()Shawn Rutledge2019-08-122-10/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ... in documentation links and in implementation, now that they have been added. The doc links to QPlatformTheme::MouseDoubleClickDistance and QPlatformTheme::TouchDoubleTapDistance were dead ends because of those being private; and user code needed a way to read the values. So now there is new API in QStyleHints. Fixes: QTBUG-76944 Change-Id: I86bce4c7fe08c9da33745a4eed450757b3a30b03 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* | | Fix unused captured 'this' warningYulong Bai2019-08-071-1/+1
| | | | | | | | | | | | | | | Change-Id: I90ddcfe42cae7364d321bd1c3a05eaba416081d4 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Fix undeclared 'memcpy' identifierYulong Bai2019-08-071-0/+1
| | | | | | | | | | | | | | | Change-Id: Ie2290a1734370ff09e499809b4342c38179131e3 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Fix incorrect vertex data and rendering when shapes change sceneSimon Hausmann2019-08-071-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When changing scene, the stroke vertices were left with uninitialized stroke colors when the item is re-attached to the scene. Marking the shape data as overall dirty and triggering a polish ensures that the data is kept in sync. Change-Id: I3f472734a97908e6e8f6e58230c0c53dcc041868 Done-with: Fabian Kosmale <fabian.kosmale@qt.io> Fixes: QTBUG-77332 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* | | Implement QSG_VISUALIZE for RHILaszlo Agocs2019-08-0715-341/+1789
| | | | | | | | | | | | | | | Change-Id: I6343f316e2ecff4e4d7454fb450a1bd0c5a917b8 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Fix tests in qtquickcontrols 1 and 2Simon Hausmann2019-08-071-26/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch partially reverts the 5.15 related #ifdefs from commit f38e071f5b353cbf9ce6c6c104bd82099ae0aa14. Those were introduced without any test coverage and our own modules (qtquickcontrols 1 and 2) were not tested with it or adapted. The change of behavior breaks our own existing code. Task-number: QTBUG-33444 Change-Id: Ie9823638c1a02281798b725f745b15e622f837c5 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* | | Fix 3+ level stencil clips on the rhi pathLaszlo Agocs2019-08-021-5/+5
| | | | | | | | | | | | | | | Change-Id: Id1e0b904ba7273e63fb63ea53c513bde20dc9759 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Change rhi-related debug prints to categorized loggingLaszlo Agocs2019-08-023-11/+12
| | | | | | | | | | | | | | | Change-Id: I4e8d3111a2f3b77e984756cc9eef49d42f0b647c Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Remove usages of deprecated QSignalMapperSona Kurazyan2019-08-012-12/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code using QSignalMapper relies on dynamic property inspection, and therefore can't use the lambda syntax for capturing the int value. Since there is only one sender object, replace QSignalMapper with a simpler mapper class, which emits the mapped signal by passing the saved member value. Task-number: QTBUG-76491 Change-Id: I6e8e527b1a92d39a1711d85c203df704c293d294 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
* | | Port from QMutex::Recursive to QRecursiveMutexMarc Mutz2019-07-316-12/+10
| | | | | | | | | | | | | | | | | | Change-Id: I5bf128b4479971e87d377707f2ebf267ccba1f1d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* | | Re-enable colors with both gl and rhi glyph cachesLaszlo Agocs2019-07-313-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Follow up to the 5.13->dev merge where the lack of the qt5 submodule update made it impossible to use the new color argument. Also implements the color argument for the rhi variant of the glyph cache. Change-Id: Ie6c6ba3d647335eb6173d0c9f7fbe3a4ed6b1f24 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Make openvg compileLaszlo Agocs2019-07-306-8/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The plugin is not tested in any form in CI, and some of the internal changes in the RHI patch has some consequences here as well. Adapt as necessary. Have not tested the plugin in practice but it compiles now. Change-Id: I482fa34802d0bd4d44570f852298c1227cf0bb71 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Have an autorelease pool for each frame on the render threadLaszlo Agocs2019-07-301-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Required with Metal. Drawables and various system resources get autoreleased and there is no pool to handle these on the SG render thread by default. This may present a slight perf hit in debug builds due to QMacAutoReleasePool doing smart but - for us - unnecessary stuff every time (so in our case, every frame) but will do for now. This complements the QRhiMetal change for not holding onto the drawable when skipping the present. The pool is essential then to prevent nextDrawable from starving and so blocking. Task-number: QTBUG-76953 Change-Id: Iaf803a0e20504d6b349d3564eda1677868fb29ef Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Avoid locking up on resize with threaded loop and the rhiLaszlo Agocs2019-07-301-4/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This was visible on X11 only because there beginFrame() happened to fail once or twice with out-of-date swapchain when there were a lot of resizes in a row. Handle this case correctly by waking up the main thread as appropriate. Change-Id: I67dc18522e1c05070267fd355095324f48259276 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Re-enable threaded render loop with Vulkan on LinuxLaszlo Agocs2019-07-301-8/+0
| | | | | | | | | | | | | | | Change-Id: I05440c54b99ddb6aac9a47e8b33a00be41c13055 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* | | Fix debug output for QQmlError when url is a resourceJan Arve Sæther2019-07-301-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | It failed to show the content of the file that had an error if the file was embedded as a resource. Change-Id: Ib8e0627919fa1f7956588ac80179adb8539df0e3 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Fix bug in QQmlEngine::setImportPathList() when it had a resource pathJan Arve Sæther2019-07-301-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The bug is really in QQmlImportDatabase::setImportPathList(). It was missing the same conversions that was done in QQmlImportDatabase::addImportPath(), so it failed to use a resource path as a import path because it did not convert ":/foo" to "qrc:/foo". We therefore just use addImportPath() to ensure the paths are converted properly. Before this, several autotests in tests/auto/qml/qqmllanguage failed on Android, since they were calling QQmlEngine::setImportPathList() where the list had resource paths. Task-number: QTBUG-73512 Change-Id: Idc64f5ad20ec665df7cb57ea1c346bc0975c3b0d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Merge remote-tracking branch 'origin/5.13' into devLiang Qi2019-07-2625-104/+253
|\| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/quick/handlers/qquickpointerdevicehandler.cpp src/quick/scenegraph/qsgdefaultglyphnode.cpp src/quick/scenegraph/qsgdefaultglyphnode_p.cpp src/quick/scenegraph/qsgdefaultglyphnode_p_p.h tests/auto/qml/qjsengine/tst_qjsengine.cpp Done-With: Jan Arve Sæther <jan-arve.saether@qt.io> Done-With: Laszlo Agocs <laszlo.agocs@qt.io> Change-Id: I35749152f8dce44b9af8d52b1283629879010f11
| * | Merge remote-tracking branch 'origin/5.12' into 5.13Qt Forward Merge Bot2019-07-245-12/+44
| |\| | | | | | | | | | Change-Id: I081bcb9cc238e6cff5f8a23b684c5d6f76dba047
| | * Do not search for Singletons from more recent versionsFabian Kosmale2019-07-231-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This would break importing older versions of a module, as we would try to locate a singleton which does not exist in this version. Fixes: QTBUG-77102 Change-Id: I78be1ec111d2be26a14b2a94bbf743cf6238cddd Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| | * Doc: fix code snippetPaul Wicking2019-07-191-1/+1
| | | | | | | | | | | | | | | | | | Task-number: QTBUG-77094 Change-Id: I9058bf7b65e8d390327af0624df611de4965f1e4 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
| | * Support text color for color fontsEskil Abrahamsen Blomfeldt2019-07-193-9/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In order to support pen color for color fonts, we have to bake the color into the cache (since the cache contains actual color data and not alpha values). This is equivalent of 78caba7ae637bf4b33631c3425eb92ec3946c99e in Qt Base. [ChangeLog][Text] Added support for text color when using color fonts. Task-number: QTBUG-74761 Change-Id: I5910636c240bd4c0ec3f0b13db4e2f78d4b062ff Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
| | * Doc: Fix typos in code snippetsPaul Wicking2019-07-181-2/+2
| | | | | | | | | | | | | | | | | | Fixes: QTBUG-77094 Change-Id: Ia974c4d8abeab48a206fb868ee5532d4aeae7319 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
| * | Doc: Add comment on evaluation order bindingsNico Vertriest2019-07-191-0/+3
| | | | | | | | | | | | | | | | | | | | | Task-number: QTBUG-73742 Change-Id: I42821823ee0315aa96da30798e35809cf0498f67 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
| * | Doc: Add doc on "quit" shortcut behavior in macOSNico Vertriest2019-07-171-0/+6
| | | | | | | | | | | | | | | | | | Task-number: QTBUG-71098 Change-Id: Ifc30bfd5abc4a889a2436c8ae977c8e988fb700f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
| * | Merge "Merge remote-tracking branch 'origin/5.12' into 5.12-merge-5.13"Edward Welbourne2019-07-174-18/+14
| |\ \
| | * | Merge remote-tracking branch 'origin/5.12' into 5.12-merge-5.13Edward Welbourne2019-07-174-18/+14
| | |\| | | | | | | | | | | | | Change-Id: I9b1cfefda23febfb24282bc30bc38865499ec2f4
| | | * QQuickItemView: refill itself before populate transitionWang Chuan2019-07-161-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The view uses a visible items list, which is maintained by the refill() method, to determine which items should be triggered to do the populate transition. The refill() was only invoked when component completed before doing the populate transition; but if the size of the view depends on the size of window (for example, using anchors.fill), more delegates could become visible after component completed. In such a case, part of visible items were not be triggered to do the transition. [ChangeLog][QtQuick][Item Views] Item views such as ListView now properly populate delegates with a populate transition when the view is resized after componentComplete. Fixes: QTBUG-76487 Change-Id: Id90c3f73d9911c8a1d6d8b1ea0c51f6c27d0ed5b Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
| | | * Fix crashes in QQmlXMLHttpRequestPavel Tumakaev2019-07-131-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ExecutionEngine::callingQmlContext() in some cases returns a null pointer. According to ISO/IEC 14882 §9.3.1/1 "If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined". Thus, invoking a QQmlContextData::resolvedUrl() member function on a null instance results in undefined behavior, and leads to a crash in some cases. ExecutionEngine::qmlEngine() in some cases returns a null pointer. The QQmlEnginePrivate::get() method must return a pointer to a QQmlEngine private internal class. Call QQmlEnginePrivate::get() with passed null pointer leads to application crash. If the QQmlEngine pointer is null, the QQmlEnginePrivate pointer should also be null. Thus, if the pointer to QQmlEngine is null pointer, the null pointer to the private class should be passed to the QQmlEnginePrivate::warning(). Task-number: QTBUG-75983 Change-Id: Iad240bb6db0be58e9087b7a86f8d400b07623865 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
| | | * Fix static buildSimon Hausmann2019-07-122-15/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use the GL attribute name helper functions only from QtQuick to avoid a clash of symbols when linking statically. Change-Id: Ic95b984092f5db222db6dc1f4ac5fb443b5ab714 Fixes: QTBUG-77012 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
| * | | V4: Add label for loop in spread in ArrayPatternErik Verbruggen2019-07-171-1/+2
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch also rotates the loop back so that the condition is at the top of the loop. It's a cherry-picked from commit 0282b89ec672e25a465a8e51bc74c7fd58a624b1. Without explicitly setting the label, we get a default constructed Label from labelForOffset in PlatformAssemblerCommon::link, which leads to a jump into nirvana. This issue arises only with backward jumps, as we fill in the information for forward jump targets once we actually encounter the target. Fixes: QTBUG-77047 Change-Id: Id928831f90eace494adb1eb1190f674a6f033b20 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| * | doc: Update the diagram to mention the correct beforeSynchronizing() signalKavindra Palaraja2019-07-176-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | Fixes: QTBUG-76602 Change-Id: I82f92c5a8e3d2f5cbc3f00516d119be532add302 Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| * | Merge remote-tracking branch 'origin/5.12' into 5.13Qt Forward Merge Bot2019-07-128-71/+181
| |\| | | | | | | | | | | | | | | | | | | | | | | | | Required a change to a #include; qquicksinglepointhandler.cpp was (at least on Android) only seeing QQuickSinglePointHandler as a forward declaration, so dereferencing it was a problem. The header that defines it does #include the one it replaces here. Change-Id: I6bc30ff9a91f55350172e4a4bcaaa7f99a2ffb28